function FinalExceptionSubscriber::onException

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/EventSubscriber/FinalExceptionSubscriber.php \Drupal\Core\EventSubscriber\FinalExceptionSubscriber::onException()
  2. 8.9.x core/lib/Drupal/Core/EventSubscriber/FinalExceptionSubscriber.php \Drupal\Core\EventSubscriber\FinalExceptionSubscriber::onException()
  3. 10 core/lib/Drupal/Core/EventSubscriber/FinalExceptionSubscriber.php \Drupal\Core\EventSubscriber\FinalExceptionSubscriber::onException()

Handles exceptions for this subscriber.

Parameters

\Symfony\Component\HttpKernel\Event\ExceptionEvent $event: The event to process.

File

core/lib/Drupal/Core/EventSubscriber/FinalExceptionSubscriber.php, line 82

Class

FinalExceptionSubscriber
Last-chance handler for exceptions: the final exception subscriber.

Namespace

Drupal\Core\EventSubscriber

Code

public function onException(ExceptionEvent $event) {
    $exception = $event->getThrowable();
    $error = Error::decodeException($exception);
    // Display the message if the current error reporting level allows this type
    // of message to be displayed, and unconditionally in update.php.
    $message = '';
    if ($this->isErrorDisplayable($error)) {
        // If error type is 'User notice' then treat it as debug information
        // instead of an error message.
        if ($error['%type'] == 'User notice') {
            $error['%type'] = 'Debug';
        }
        $error = $this->simplifyFileInError($error);
        unset($error['backtrace'], $error['exception'], $error['severity_level']);
        if (!$this->isErrorLevelVerbose()) {
            // Without verbose logging, use a simple message.
            // We use \Drupal\Component\Render\FormattableMarkup directly here,
            // rather than use t() since we are in the middle of error handling, and
            // we don't want t() to cause further errors.
            $message = new FormattableMarkup(Error::DEFAULT_ERROR_MESSAGE, $error);
        }
        else {
            // With verbose logging, we will also include a backtrace.
            $backtrace_exception = $exception;
            while ($backtrace_exception->getPrevious()) {
                $backtrace_exception = $backtrace_exception->getPrevious();
            }
            $backtrace = $backtrace_exception->getTrace();
            // First trace is the error itself, already contained in the message.
            // While the second trace is the error source and also contained in the
            // message, the message doesn't contain argument values, so we output it
            // once more in the backtrace.
            array_shift($backtrace);
            // Generate a backtrace containing only scalar argument values.
            $error['@backtrace'] = Error::formatBacktrace($backtrace);
            $message = new FormattableMarkup(Error::DEFAULT_ERROR_MESSAGE . ' <pre class="backtrace">@backtrace</pre>', $error);
        }
    }
    $content_type = $event->getRequest()
        ->getRequestFormat() == 'html' ? 'text/html' : 'text/plain';
    $content = $this->t('The website encountered an unexpected error. Try again later.');
    $content .= $message ? '<br><br>' . $message : '';
    $response = new Response($content, 500, [
        'Content-Type' => $content_type,
    ]);
    if ($exception instanceof HttpExceptionInterface) {
        $response->setStatusCode($exception->getStatusCode());
        $response->headers
            ->add($exception->getHeaders());
    }
    else {
        $response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR, '500 Service unavailable (with message)');
    }
    $event->setResponse($response);
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.