diff -u b/includes/bootstrap.inc b/includes/bootstrap.inc --- b/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -1076,15 +1076,59 @@ static $errors_triggered = array(); if (empty($errors_triggered[$type][$name][$error_type])) { if ($error_type == 'missing') { - trigger_error(format_string('The following @type is missing from the file system: %name. In order to fix this, put the @type back in its original location. For more information, see the documentation page.', array('@type' => $type, '%name' => $name, '@documentation' => 'https://www.drupal.org/node/2487215')), E_USER_WARNING); + _drupal_trigger_error_safe(format_string('The following @type is missing from the file system: %name. In order to fix this, put the @type back in its original location. For more information, see the documentation page.', array('@type' => $type, '%name' => $name, '@documentation' => 'https://www.drupal.org/node/2487215')), E_USER_WARNING); } elseif ($error_type == 'moved') { - trigger_error(format_string('The following @type has moved within the file system: %name. In order to fix this, clear caches or put the @type back in its original location. For more information, see the documentation page.', array('@type' => $type, '%name' => $name, '@documentation' => 'https://www.drupal.org/node/2487215')), E_USER_WARNING); + _drupal_trigger_error_safe(format_string('The following @type has moved within the file system: %name. In order to fix this, clear caches or put the @type back in its original location. For more information, see the documentation page.', array('@type' => $type, '%name' => $name, '@documentation' => 'https://www.drupal.org/node/2487215')), E_USER_WARNING); } $errors_triggered[$type][$name][$error_type] = TRUE; } } +/** + * Delays trigger_error() calls until Drupal has been fully bootstrapped. + * + * This is a Safe alternative for PHP's internal trigger_error(). + * The Drupal error handler will add a watchdog message. Adding a watchdog + * message is not a safe operation before Drupal has been fully boostrapped. + * This function will delay trigger_error() calls until Drupal has been fully + * bootstrapped. If Drupal is already fully bootstrapped, this function will + * directly call the internal PHP trigger_error(). + * + * @param $error_msg + * The designated error message for this error. It's limited to 1024 bytes in + * length. Any additional characters beyond 1024 bytes will be truncated. + * @param int $error_type + * The designated error type for this error. It only works with the E_USER + * family of constants, and will default to E_USER_NOTICE. + * + * @see trigger_all_queued_errors() + */ +function _drupal_trigger_error_safe($error_msg, $error_type = E_USER_NOTICE) { + if (drupal_get_bootstrap_phase() == DRUPAL_BOOTSTRAP_FULL) { + trigger_error($error_msg, $error_type); + return; + } + + // It is not yet safe to trigger an error, so queue it up. + $errors = &drupal_static(__FUNCTION__, array()); + $errors[] = array($error_msg, $error_type); +} + +/** + * Calls a trigger_error() for all queued errors. + * + * @see trigger_all_queued_errors() + * @see _drupal_bootstrap_full() + */ +function _drupal_trigger_all_queued_errors() { + $errors = &drupal_static('_drupal_trigger_error_safe', array()); + + foreach ($errors as $error_parameters) { + call_user_func_array('trigger_error', $error_parameters); + } +} + /** * Writes the file scan cache to the persistent cache. * diff -u b/includes/common.inc b/includes/common.inc --- b/includes/common.inc +++ b/includes/common.inc @@ -2757,7 +2757,6 @@ _registry_check_code(REGISTRY_WRITE_LOOKUP_CACHE); drupal_cache_system_paths(); module_implements_write_cache(); - drupal_file_scan_write_cache(); system_run_automated_cron(); } @@ -2768,6 +2767,7 @@ _registry_check_code(REGISTRY_WRITE_LOOKUP_CACHE); drupal_cache_system_paths(); module_implements_write_cache(); + drupal_file_scan_write_cache(); system_run_automated_cron(); } @@ -5270,6 +5270,11 @@ drupal_theme_initialize(); module_invoke_all('init'); } + + // Execute all the delayed trigger_error()'s. Some errors are delayed because + // trigger_error() causes a watchdog call which is not a safe operation + // before Drupal is fully bootstrapped. + _drupal_trigger_all_queued_errors(); } /**