}
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
$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);
}
/**
- * 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
* @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) {
// 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());
$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.