123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- <?php
- namespace Drupal\Core\EventSubscriber;
- use Symfony\Component\EventDispatcher\EventSubscriberInterface;
- use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
- use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
- use Symfony\Component\HttpKernel\KernelEvents;
- /**
- * Utility base class for exception subscribers.
- *
- * A subscriber may extend this class and implement getHandledFormats() to
- * indicate which request formats it will respond to. Then implement an on*()
- * method for any error code (HTTP response code) that should be handled. For
- * example, to handle a specific error code like 404 Not Found messages add the
- * method:
- *
- * @code
- * public function on404(GetResponseForExceptionEvent $event) {}
- * @endcode
- *
- * To implement a fallback for the entire 4xx class of codes, implement the
- * method:
- *
- * @code
- * public function on4xx(GetResponseForExceptionEvent $event) {}
- * @endcode
- *
- * That method should then call $event->setResponse() to set the response object
- * for the exception. Alternatively, it may opt not to do so and then other
- * listeners will have the opportunity to handle the exception.
- *
- * Note: Core provides several important exception listeners by default. In most
- * cases, setting the priority of a contrib listener to the default of 0 will
- * do what you expect and handle the exceptions you'd expect it to handle.
- * If a custom priority is set, be aware of the following core-registered
- * listeners.
- *
- * - Fast404ExceptionHtmlSubscriber: 200. This subscriber will return a
- * minimalist, high-performance 404 page for HTML requests. It is not
- * recommended to have a priority higher than this one as it will only slow
- * down that use case.
- * - ExceptionLoggingSubscriber: 50. This subscriber logs all exceptions but
- * does not handle them. Do not register a listener with a higher priority
- * unless you want exceptions to not get logged, which makes debugging more
- * difficult.
- * - DefaultExceptionSubscriber: -256. The subscriber of last resort, this will
- * provide generic handling for any exception. A listener with a lower
- * priority will never get called.
- *
- * All other core-provided exception handlers have negative priorities so most
- * module-provided listeners will naturally take precedence over them.
- */
- abstract class HttpExceptionSubscriberBase implements EventSubscriberInterface {
- /**
- * Specifies the request formats this subscriber will respond to.
- *
- * @return array
- * An indexed array of the format machine names that this subscriber will
- * attempt to process, such as "html" or "json". Returning an empty array
- * will apply to all formats.
- *
- * @see \Symfony\Component\HttpFoundation\Request
- */
- abstract protected function getHandledFormats();
- /**
- * Specifies the priority of all listeners in this class.
- *
- * The default priority is 1, which is very low. To have listeners that have
- * a "first attempt" at handling exceptions return a higher priority.
- *
- * @return int
- * The event priority of this subscriber.
- */
- protected static function getPriority() {
- return 0;
- }
- /**
- * Handles errors for this subscriber.
- *
- * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
- * The event to process.
- */
- public function onException(GetResponseForExceptionEvent $event) {
- $exception = $event->getException();
- // Make the exception available for example when rendering a block.
- $request = $event->getRequest();
- $request->attributes->set('exception', $exception);
- $handled_formats = $this->getHandledFormats();
- $format = $request->query->get(MainContentViewSubscriber::WRAPPER_FORMAT, $request->getRequestFormat());
- if ($exception instanceof HttpExceptionInterface && (empty($handled_formats) || in_array($format, $handled_formats))) {
- $method = 'on' . $exception->getStatusCode();
- // Keep just the leading number of the status code to produce either a
- // on400 or a 500 method callback.
- $method_fallback = 'on' . substr($exception->getStatusCode(), 0, 1) . 'xx';
- // We want to allow the method to be called and still not set a response
- // if it has additional filtering logic to determine when it will apply.
- // It is therefore the method's responsibility to set the response on the
- // event if appropriate.
- if (method_exists($this, $method)) {
- $this->$method($event);
- }
- elseif (method_exists($this, $method_fallback)) {
- $this->$method_fallback($event);
- }
- }
- }
- /**
- * Registers the methods in this class that should be listeners.
- *
- * @return array
- * An array of event listener definitions.
- */
- public static function getSubscribedEvents() {
- $events[KernelEvents::EXCEPTION][] = ['onException', static::getPriority()];
- return $events;
- }
- }
|