]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-20676 improved output buffer workaround when printing fatal errors
authorPetr Skoda <skodak@moodle.org>
Fri, 30 Oct 2009 13:44:07 +0000 (13:44 +0000)
committerPetr Skoda <skodak@moodle.org>
Fri, 30 Oct 2009 13:44:07 +0000 (13:44 +0000)
lib/outputrenderers.php
lib/setuplib.php

index c1f34e937d7f04d4e2a1a9ac321c3ec6a9f43da4..bac96c6a5c93a2b121815aac65fa580076e0a4fc 100644 (file)
@@ -1923,8 +1923,18 @@ class moodle_core_renderer extends moodle_renderer_base {
         }
 
         if ($this->has_started()) {
+            // we can not always recover properly here, we have problems with output buffering,
+            // html tables, etc.
             $output .= $this->opencontainers->pop_all_but_last();
+
         } else {
+            // It is really bad if library code throws exception when output buffering is on,
+            // because the buffered text would be printed before our start of page.
+            // NOTE: this hack might be behave unexpectedly in case output buffering is enabled in PHP.ini
+            while (ob_get_level() > 0) {
+                ob_end_clean();
+            }
+            
             // Header not yet printed
             if (isset($_SERVER['SERVER_PROTOCOL'])) {
                                // server protocol should be always present, because this render
index fe026d35683da8952b95da8db250ed870a51c885..2dc21fbf650e79051d04c8cdf3e9e686aa277d04 100644 (file)
@@ -208,7 +208,7 @@ function default_exception_handler($ex, $isupgrade = false, $plugin = null) {
         $CFG->debug = DEBUG_DEVELOPER;
     }
 
-    if (is_stacktrace_during_output_init($backtrace)) {
+    if (is_early_init($backtrace)) {
         echo bootstrap_renderer::early_error($message, $moreinfourl, $link, $backtrace, $debuginfo);
     } else {
         echo $OUTPUT->fatal_error($message, $moreinfourl, $link, $backtrace, $debuginfo);
@@ -222,8 +222,8 @@ function default_exception_handler($ex, $isupgrade = false, $plugin = null) {
 }
 
 /**
- * This function encapsulates the tests for whether an exception was thrown in the middle
- * of initialising the $OUTPUT variable and starting output.
+ * This function encapsulates the tests for whether an exception was thrown in
+ * early init -- either during setup.php or during init of $OUTPUT.
  *
  * If another exception is thrown then, and if we do not take special measures,
  * we would just get a very cryptic message "Exception thrown without a stack
@@ -233,10 +233,11 @@ function default_exception_handler($ex, $isupgrade = false, $plugin = null) {
  * @param array $backtrace the stack trace to analyse.
  * @return boolean whether the stack trace is somewhere in output initialisation.
  */
-function is_stacktrace_during_output_init($backtrace) {
+function is_early_init($backtrace) {
     $dangerouscode = array(
         array('function' => 'header', 'type' => '->'),
         array('class' => 'bootstrap_renderer'),
+        array('file' => dirname(__FILE__).'/setup.php'),
     );
     foreach ($backtrace as $stackframe) {
         foreach ($dangerouscode as $pattern) {
@@ -271,16 +272,10 @@ function print_error($errorcode, $module = 'error', $link = '', $a = null) {
     // Errors in unit test become exceptions, so you can unit test code that might call print_error().
     if (!empty($UNITTEST->running)) {
         throw new moodle_exception($errorcode, $module, $link, $a);
-    } else {
-        // It is really bad if library code calls print_error when output buffering
-        // is on.
-        while (ob_get_level() > 0) {
-            ob_end_clean();
-        }
     }
 
     list($message, $moreinfourl, $link) = prepare_error_message($errorcode, $module, $link, $a);
-    if (is_stacktrace_during_output_init(debug_backtrace())) {
+    if (is_early_init(debug_backtrace())) {
         echo bootstrap_renderer::early_error($message, $moreinfourl, $link, debug_backtrace());
     } else {
         echo $OUTPUT->fatal_error($message, $moreinfourl, $link, debug_backtrace());
@@ -865,7 +860,7 @@ class bootstrap_renderer {
             $backtrace = debug_backtrace();
             array_shift($backtrace);
             array_shift($backtrace);
-            $recursing = is_stacktrace_during_output_init($backtrace);
+            $recursing = is_early_init($backtrace);
         }
 
         // If lib/outputlib.php has been loaded, call it.