From 3c1ea58b46d097dbd87fd06e1c72bdfd0257418a Mon Sep 17 00:00:00 2001 From: Petr Skoda Date: Sat, 31 Oct 2009 15:01:25 +0000 Subject: [PATCH] MDL-20691 "Fatal error: Exception thrown without a stack frame in Unknown on line 0" workaround in $OUTPUT->print_error() --- lib/setuplib.php | 52 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/lib/setuplib.php b/lib/setuplib.php index 9e3d89b95f308..a76ea1ae8ee13 100644 --- a/lib/setuplib.php +++ b/lib/setuplib.php @@ -180,6 +180,7 @@ function default_exception_handler($ex) { // note: transaction blocks should never change current $_SESSION $DB->rollback_sql(); } catch (Exception $ignored) { + // default exception handler MUST not throw any exceptions!! } } @@ -193,7 +194,16 @@ function default_exception_handler($ex) { if (is_early_init($info->backtrace)) { echo bootstrap_renderer::early_error($info->message, $info->moreinfourl, $info->link, $info->backtrace, $info->debuginfo); } else { - echo $OUTPUT->fatal_error($info->message, $info->moreinfourl, $info->link, $info->backtrace, $info->debuginfo); + try { + echo $OUTPUT->fatal_error($info->message, $info->moreinfourl, $info->link, $info->backtrace, $info->debuginfo); + } catch (Exception $out_ex) { + // default exception handler MUST not throw any exceptions!! + // the problem here is we do not know if page already started or not, we only know that somebody messed up in outputlib or theme + // so we just print at least something instead of "Exception thrown without a stack frame in Unknown on line 0":-( + echo bootstrap_renderer::early_error_content($info->message, $info->moreinfourl, $info->link, $info->backtrace, $info->debuginfo); + $outinfo = get_exception_info($out_ex); + echo bootstrap_renderer::early_error_content($outinfo->message, $outinfo->moreinfourl, $outinfo->link, $outinfo->backtrace, $outinfo->debuginfo); + } } exit(1); // General error code @@ -868,12 +878,34 @@ public function __call($method, $arguments) { } /** - * This function should only be called by this class, or from exception handlers + * Returns nicely formated error message in a div box. * @return string */ - public static function early_error($message, $moreinfourl, $link, $backtrace, $debuginfo = null) { + public static function early_error_content($message, $moreinfourl, $link, $backtrace, $debuginfo = null) { global $CFG; + $content = '
+' . $message . ' +
'; + if (!empty($CFG->debug) && $CFG->debug >= DEBUG_DEVELOPER) { + if (!empty($debuginfo)) { + $content .= '
Debug info: ' . s($debuginfo) . '
'; + } + if (!empty($backtrace)) { + $content .= '
Stack trace: ' . format_backtrace($backtrace, false) . '
'; + } + } + + return $content; + } + + /** + * This function should only be called by this class, or from exception handlers + * @return string + */ + public static function early_error($message, $moreinfourl, $link, $backtrace, $debuginfo = null) { // In the name of protocol correctness, monitoring and performance // profiling, set the appropriate error headers for machine comsumption if (isset($_SERVER['SERVER_PROTOCOL'])) { @@ -896,19 +928,7 @@ public static function early_error($message, $moreinfourl, $link, $backtrace, $d $strerror = 'Error'; } - $content = '
-' . $message . ' -
'; - if (!empty($CFG->debug) && $CFG->debug >= DEBUG_DEVELOPER) { - if (!empty($debuginfo)) { - $content .= '
' . $debuginfo . '
'; - } - if (!empty($backtrace)) { - $content .= '
Stack trace: ' . format_backtrace($backtrace, false) . '
'; - } - } + $content = self::early_error_content($message, $moreinfourl, $link, $backtrace, $debuginfo); return self::plain_page($strerror, $content); }