Whoops, I Forgot The Error Handler

Ever experienced HTTP 500’s, but found that your error logs are empty. Ever had no clue why or how this could be happening? Perhaps you forgot to enable the Whoops error handler.

That’s right, perhaps, when you were setting up a Zend Expressive application, you made the mistake which I made recently when you used the Zend Expressive Skeleton Installer, and were asked the following question:

Which error handler do you want to use during development?
  [1] Whoops
  [n] None of the above

What was your selection? I’m guessing that it might have been n. Now, why is this important? It’s important, because if you chose n, and used a templating engine, then TemplatedErrorHandler, would have been used as PHP's default exception handler.

As a result, no exceptions will be written in your logs. Sure, you’ll see that a 500 error has occurred somewhere in your application. But, the only information you’ll have is the following — not so very helpful — error message:

This is awkward.

We encountered a 500 error.

At this point, as most of us likely would, we’d then go and have a look at the log files, expecting to see a stack trace or at least some basic kind of information about what caused the error.

Sadly, you won’t find a thing. There’ll be no information there. No matter how often you re-request the URI, the logs will contain no more detailed information than they’ve already shown you.

At this point, you might start blaming your environment. But, if you check your PHP settings, you may very well see that all logging is enabled.

You’ll likely also see that it’s configured to be either written out to the log file you were tailing, or to a service, which you were watching. If so, I’d not blame you for scratching your head and wondering why you do not see any exception information.

If you’ve found yourself in this situation, then the first thing I suggest you do is to stop doubting your SysAdmin and DevOps skills. Stop also questioning the setup of your environment. Perhaps it was something as simple as not enabling Whoops.

Instead, check if you have config/autoload/errorhandler.local.php available. If not, then create it, and add in the following configuration:

use Whoops\Handler\PrettyPageHandler;
use Zend\Expressive\Container\WhoopsErrorHandlerFactory;

return [
    'dependencies' => [
        'invokables' => [
            'Zend\Expressive\Whoops' => Whoops\Run::class,
            'Zend\Expressive\WhoopsPageHandler' => PrettyPageHandler::class,
        'factories' => [
            'Zend\Expressive\FinalHandler' => WhoopsErrorHandlerFactory::class,

    'whoops' => [
        'json_exceptions' => [
            'display'    => true,
            'show_trace' => true,
            'ajax_only'  => true,

By using the .local.php file suffix, this will ensure that error handling only will be enabled in development, and not in any production environment.

That is unless you’ve accidentally updated the default .gitignore configuration, which excludes files with this prefix from being stored under version control.

With the new configuration added, reload your application and see if you now start to see more detailed error information, such as in the screenshot below, displayed in all its glory by the excellent Whoops error handler:

"the whoops error handler"

Why Such a Setup?

This might seem like a bit of an illogical thing to do. But, think about it from the flip side. Would you want all kinds of information accidentally leaking out in production?

Would you want information about the internals of your application being made known to people who don’t have the most honorable of intentions? I’d think not. However, I hear that a compromise is almost ready.

Zend Framework project team lead, Matthew Weier O’Phinney, has been working on a revised solution for error handling, which you can read about in a recent commit of his.

This new approach, which is a prototype for error handling in the next version of Zend Expressive, provide a much more robust, more flexible approach handling errors when developing with expressive.

This looks like a very exciting development indeed. So stay tuned to the Zend Expressive repository for further updates (or consider getting in and contributing).

In Conclusion

So, if you’ve found yourself in the same situation as I was, having little rants about how difficult it is to enable logging in Docker, step back and look at your Zend Expressive error handling configuration. Perhaps that’s where the problem lies.

About Matthew

Matthew Setter Matthew Setter is a PHP & Zend Framework specialist. If you're in need of a custom software application, need to migrate an existing legacy application, or want to know your current application's GPA - get in touch.

Want To Be A Zend Framework Guru?

Drop your email in the box below, and get awesome tutorialsjust like this one — straight to your inbox, PLUS exclusive content only available by email.