Change record status: 
Project: 
Introduced in branch: 
8.0.x
Introduced in version: 
8.x
Description: 

In earlier iterations of Drupal 8 exception handling, particularly for HTTP-related exceptions, was all wrapped up in a single in-extensible class. It has now been broken down to smaller parts that make use of the kernel exception event directly. As a result, contrib modules may participate in the exception handling process more cleanly.

The exception event

The KernelEvents::EXCEPTION event is fired by the Symfony HttpKernel any time an exception is allowed to bubble up to the level of the kernel. Each listener is fired in turn until one of them sets a Response object on the event, at which point that Response is returned and no further listeners are fired.

Note: Allowing non-HTTP exceptions to bubble up to the Kernel is strongly discouraged! Most exceptions should be handled more gracefully closer to the source of the error, and if necessary may be converted into an Http exception (eg, for an HTTP 50x response code).

Exception event listeners may take action other than fully handling the response. For example, the ExceptionLoggingSubscriber will log all exceptions but not handle the exception, allowing later listeners to do so.

HTTP Exceptions

If the thrown exception is an HttpException, a utility base class is provided to simplify handling. Subscriber classes may extend \Drupal\Core\EventSubscriber\HttpExceptionSubscriberBase and implement one or two of the available methods, then whatever methods are appropriate for the HTTP status code in question. For example, the following subscriber will handle 404 messages for SVG requests, and only SVG requests. Any non-404, non-SVG request will be ignored and left for other listeners.


namespace Drupal\mymodule\EventSubscriber;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;

class ExceptionSvgSubscriber extends HttpExceptionSubscriberBase {

  /**
   * {@inheritDoc}
   */
  protected function getHandledFormats() {
    // This assumes that "svg" has already been registered as a supported format in the system.
    return ['svg'];
  }

  /**
   * {@inheritdoc}
   */
  protected static function getPriority() {
    // Most default subscribers have a negative priority, so the default of 0 will happen first.
    // Any listener priority may be specified here.
    return 0;
  }

  /**
   * Handles a 404 error for SVG.
   *
   * Any method named on . $http_code will be called with the event object for the corresponding
   * HTTP status code. Any number of listeners may be registered in this class by simply giving them
   * the appropriate method name.
   *
   * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
   *   The event to process.
   */
  public function on404(GetResponseForExceptionEvent $event) {
    $response = new Response("<svg><text>File not found</text></svg>", Response::HTTP_NOT_FOUND);
    $event->setResponse($response);
  }
}
Impacts: 
Module developers