Direkt zum Inhalt

Drupal 8: Catch that exception

Drupal 8 embraced the principle of throwing exceptions when something bad happens in code. There is no graceful degradation of services, just a big white screen of death (WSOD) that looks something like this:

Drupal 8 - WSOD


When an error happens, Drupal will come to a dead stop. This is good for developers during the development phase because they can clearly see that something is not working as it should, but it's not so good for site visitors later on when the site is live.

What can you do to prevent this?

Well, you have two options. The first option is to fix all bugs in your code. But since you are probably using a bunch of contributed modules that may have bugs, that's not always possible. You must watch for errors and react accordingly. To do this, you can just visit the Recent log messages in Drupal once in a while, or you can do something more interesting.

For example, thanks to the Event subscribers and KernelEvents::EXCEPTION event you can catch any exception and send it to email or Slack. By subscribing to this event you can create a response for exceptions thrown anywhere in your code, or you can modify the thrown exception.

To react on the EXCEPTION event, create an EventSubscriber in your custom module and implement the following method:

public static function getSubscribedEvents() {
  $events[KernelEvents::EXCEPTION][] = ['onException', 60];
  return $events;
}

All you have to do now, is to implement the onException method. You can get the exception like this:

public function onException(GetResponseForExceptionEvent $event) {
  $exception = $event->getException();
  ...
  ...
}

To get the most interesting information about the thrown exception you can do something like this:

$exception_message = $exception->getMessage();
$exception_file = $exception->getFile();
$exception_line = $exception->getLine();

I created a simple module that sends exceptions to Slack, so you can head over to my Github page and check it out:
https://github.com/gnikolovski/send_me_errors

The second option is to catch the exception and modify it. Let's see how easy is to replace the thrown exception message with something that your users will understand more clearly:

use Symfony\Component\HttpFoundation\Response;

public function onException(GetResponseForExceptionEvent $event) {
  return $event->setResponse(new Response('We are having technical difficulties and are actively working on a fix. Please try again in a few minutes.'));
}

Instead of that ugly WSOD, you get a nice message that is much more meaningful to the non-technical users. You can also perform a redirection to a page that explains that the site is experiencing technical difficulties.