@@ -343,6 +343,67 @@ function __construct($debuginfo = NULL) {
343
343
}
344
344
}
345
345
346
+ /**
347
+ * Get the Whoops! handler.
348
+ *
349
+ * @return \Whoops\Run|null
350
+ */
351
+ function get_whoops (): ?\Whoops \Run {
352
+ global $ CFG ;
353
+
354
+ if (CLI_SCRIPT || AJAX_SCRIPT ) {
355
+ return null ;
356
+ }
357
+
358
+ if (defined ('PHPUNIT_TEST ' ) && PHPUNIT_TEST ) {
359
+ return null ;
360
+ }
361
+
362
+ if (defined ('BEHAT_TEST ' ) && BEHAT_TEST ) {
363
+ return null ;
364
+ }
365
+
366
+ if (!$ CFG ->debugdisplay ) {
367
+ return null ;
368
+ }
369
+
370
+ if (!$ CFG ->debug_developer_use_pretty_exceptions ) {
371
+ return null ;
372
+ }
373
+
374
+ $ composerautoload = "{$ CFG ->dirroot }/vendor/autoload.php " ;
375
+ if (file_exists ($ composerautoload )) {
376
+ require_once ($ composerautoload );
377
+ }
378
+
379
+ if (!class_exists (\Whoops \Run::class)) {
380
+ return null ;
381
+ }
382
+
383
+ // We have Whoops available, use it.
384
+ $ whoops = new \Whoops \Run ();
385
+
386
+ // Append a custom handler to add some more information to the frames.
387
+ $ whoops ->appendHandler (function ($ exception , $ inspector , $ run ) {
388
+ // Moodle exceptions often have a link to the Moodle docs pages for them.
389
+ // Add that to the first frame in the stack.
390
+ $ info = get_exception_info ($ exception );
391
+ if ($ info ->moreinfourl ) {
392
+ $ collection = $ inspector ->getFrames ();
393
+ $ collection [0 ]->addComment ("{$ info ->moreinfourl }" , 'More info ' );
394
+ }
395
+ });
396
+
397
+ // Add the Pretty page handler. It's the bee's knees.
398
+ $ handler = new \Whoops \Handler \PrettyPageHandler ();
399
+ if (isset ($ CFG ->debug_developer_editor )) {
400
+ $ handler ->setEditor ($ CFG ->debug_developer_editor ?: null );
401
+ }
402
+ $ whoops ->appendHandler ($ handler );
403
+
404
+ return $ whoops ;
405
+ }
406
+
346
407
/**
347
408
* Default exception handler.
348
409
*
@@ -366,6 +427,11 @@ function default_exception_handler($ex) {
366
427
// should be either empty or the length of the error page.
367
428
@header_remove ('Content-Length ' );
368
429
430
+ if ($ whoops = get_whoops ()) {
431
+ // If whoops is available we will use it. The get_whoops() function checks whether all conditions are met.
432
+ $ whoops ->handleException ($ ex );
433
+ }
434
+
369
435
if (is_early_init ($ info ->backtrace )) {
370
436
echo bootstrap_renderer::early_error ($ info ->message , $ info ->moreinfourl , $ info ->link , $ info ->backtrace , $ info ->debuginfo , $ info ->errorcode );
371
437
} else {
@@ -422,6 +488,10 @@ function default_exception_handler($ex) {
422
488
* @return bool false means use default error handler
423
489
*/
424
490
function default_error_handler ($ errno , $ errstr , $ errfile , $ errline ) {
491
+ if ($ whoops = get_whoops ()) {
492
+ // If whoops is available we will use it. The get_whoops() function checks whether all conditions are met.
493
+ $ whoops ->handleError ($ errno , $ errstr , $ errfile , $ errline );
494
+ }
425
495
if ($ errno == 4096 ) {
426
496
//fatal catchable error
427
497
throw new coding_exception ('PHP catchable fatal error ' , $ errstr );
0 commit comments