6

In /core/includes/errors.inc, when there is a fatal error it outputs a response with the message "The website encountered an unexpected error. Please try again later." and a back-trace, if error_level is set to verbose, and without the back-trace otherwise.

It seems like at this point, there's no way, with an event subscriber to capture the response and alter it.

Is that correct?

Or is there a way to wrap the output from line 268 of errors.inc in Drupal 8.4 with markup?

Note, there's another answer that works if it's not a fatal error, but that doesn't offer a complete solution.

Also, I looked into .htaccess and Apache ErrorDocument directive, but that was misguided. Once Apache passes off to PHP, it can no longer use that directive. That's for real server errors.

3

Symfony's HttpKernel uses the event dispatcher to allow subscribers to handle exceptions and send custom responses. Only if no subscriber does so will it throw the exception further up and let it reach the global error handler. (At which point it's indeed too late to do anything else.)

Drupal already comes with such a subscriber (or rather several of them, which check particular conditions) for HTTP exceptions (These are implementors of \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface, such as NotFoundHttpException.)

If you absolutely need to intercept non-HTTP exceptions wherever they happen, and return custom responses, you can create your own subscriber (see Drupal\Core\EventSubscriber\HttpExceptionSubscriberBase), and give it a very low priority (< -128) to avoid interfering with the core HTTP exception subscribers.

However, architecture-wise I would suggest this is not a good way to go. If you have a controller that triggers a particular exception, then it should catch it and throw the appropriate HTTP exception instead. This also requires much, much less code than messing around with event subscribers. ;)

If need be, you can even throw a ServiceUnavailableHttpException (503) or set a custom status like new HttpException(500) if there is no class for it.

Drupal core's exception subscribers don't actually handle 5xx errors, but you can create your own that does, which would probably look something like the following:

class Custom5xxHtmlSubscriber extends HttpExceptionSubscriberBase {
  public function on5xx(GetResponseForExceptionEvent $event) {
     // Do stuff
     (new Response())->send();
  }

With a corresponding service definition like the following:

  custom5xxsubscriber:
    class: ...
    tags:
      - { name: event_subscriber }
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.