Whoops, I Forgot The Error Handler

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.

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.

Do you need to get your head around Docker Compose quickly?

What about needing to dockerize existing applications to make them easier to deploy, reducing the time required for develwpers to get started on projects, or learning how to debug an existing Docker Compose-based app? Then this free book is for you!

You might also be interested in these tutorials too...

Tue, Oct 4, 2016

How to Simplify Expressive Configuration with Interop-Config

Want a simpler way to configure a Zend Expressive application? Want to simplify how it’s done, yet still be sufficiently expressive enough, that it’s easy to read and maintain? Then it’s time you got to know Interop-Config by Sandro Keil.

Mon, Aug 22, 2016

How To Use Laravel’s Eloquent ORM with Zend Expressive

Laravel’s Eloquent ORM isn’t likely the first one you think of when using Zend Expressive. You likely think of Zend\Db or Doctrine. But, with a little bit of work, it’s possible to use Eloquent with Expressive. Today’s tutorial shows you how - step-by-step.

Want more tutorials like this?

If so, enter your email address in the field below and click subscribe.

You can unsubscribe at any time by clicking the link in the footer of the emails you'll receive. Here's my privacy policy, if you'd like to know more. I use Mailchimp to send emails. You can learn more about their privacy practices here.

Join the discussion

comments powered by Disqus