From df272345bad47b0696a608b1dc1cc3a978fba4dd Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Sat, 22 Jun 2019 11:38:43 +0200 Subject: [PATCH] MDL-65996 exceptions: Make exception handler early-errors compliant Some errors can happen really early in Moodle bootstrap/warmup (basically when executing setup.php stuff, before general libraries are loaded and available). That's called "early errors" and there are good parts within setuplib.php that must be able to run without any dependency other than vanilla php code. It seems that, along the years, some dependencies have been added (calls to debugging(), to s()....) and they worked mostly ok because early errors are rare. This commit just makes all those dependencies conditional so, if an early error is detected... the exception handler will return real information about he error happening and not handler own errors (like it's happening now). --- lib/setuplib.php | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/lib/setuplib.php b/lib/setuplib.php index 5db32cec958..f291a6dfc1f 100644 --- a/lib/setuplib.php +++ b/lib/setuplib.php @@ -362,14 +362,14 @@ function default_exception_handler($ex) { $info = get_exception_info($ex); - if (debugging('', DEBUG_MINIMAL)) { - $logerrmsg = "Default exception handler: ".$info->message.' Debug: '.$info->debuginfo."\n".format_backtrace($info->backtrace, true); - error_log($logerrmsg); - } - if (is_early_init($info->backtrace)) { echo bootstrap_renderer::early_error($info->message, $info->moreinfourl, $info->link, $info->backtrace, $info->debuginfo, $info->errorcode); } else { + if (debugging('', DEBUG_MINIMAL)) { + $logerrmsg = "Default exception handler: ".$info->message.' Debug: '.$info->debuginfo."\n".format_backtrace($info->backtrace, true); + error_log($logerrmsg); + } + try { if ($DB) { // If you enable db debugging and exception is thrown, the print footer prints a lot of rubbish @@ -569,7 +569,12 @@ function get_exception_info($ex) { if (!empty($CFG->errordocroot)) { $errordoclink = $CFG->errordocroot . '/en/'; } else { - $errordoclink = get_docs_url(); + // Only if the function is available. May be not for early errors. + if (function_exists('current_language')) { + $errordoclink = get_docs_url(); + } else { + $errordoclink = 'https://docs.moodle.org/en/'; + } } if ($module === 'error') { @@ -1971,7 +1976,15 @@ width: 80%; -moz-border-radius: 20px; padding: 15px"> $debug = $debug || (!empty($CFG->config_php_settings['debug']) && $CFG->config_php_settings['debug'] >= DEBUG_DEVELOPER ); if ($debug) { if (!empty($debuginfo)) { - $debuginfo = s($debuginfo); // removes all nasty JS + // Remove all nasty JS. + if (function_exists('s')) { // Function may be not available for some early errors. + $debuginfo = s($debuginfo); + } else { + // Because weblib is not available for these early errors, we + // just duplicate s() code here to be safe. + $debuginfo = preg_replace('/&#(\d+|x[0-9a-f]+);/i', '&#$1;', + htmlspecialchars($debuginfo, ENT_QUOTES | ENT_HTML401 | ENT_SUBSTITUTE)); + } $debuginfo = str_replace("\n", '
', $debuginfo); // keep newlines $content .= '
Debug info: ' . $debuginfo . '
'; } @@ -2107,9 +2120,11 @@ width: 80%; -moz-border-radius: 20px; padding: 15px"> } $footer = ''; - if (MDL_PERF_TEST) { - $perfinfo = get_performance_info(); - $footer = ''; + if (function_exists('get_performance_info')) { // Function may be not available for some early errors. + if (MDL_PERF_TEST) { + $perfinfo = get_performance_info(); + $footer = ''; + } } return '