Slim-OO Part 6 – Debugging Made Easy

Part 6 – Debugging Made Easy

Whoops!

Whoops! We had an error and now we have to look at that ugly, fairly uninformative error page. How many times has that happened to you? Too many? Yeah, same here. I really hate those uninformative “Hey, something broke but we’re not going to tell you what” errors.

Now I will say, the guys at Slim have made some improvements to the default PHP error page. We now get a message, file/line, and a simple stack dump. This is something I really appreciate as it at least gives you a place to start looking. But I would still like to see more.

Thanks to Zeuxis Lo we now have a slim port of the very cool Whoops debug library. Whoops takes that basic stack trace and actually shows you a view into each file/line. Giving you a code view for all frames in a stack trace with line highlights. It also gives you all of your environment variables and their details. This looks much better than the default PHP or Slim error pages.

alt text

Middleware.

We’ll be adding this as a middleware.

What’s middleware you ask? Well, by definition middleware is…

Code that changes the default application behavior and can be added at different stages during the request/response cycle.

In other words, you can hook into your application before and after specific points during the execution; Allowing us to modify either the Request or the Response. This can be very useful for automatically handling things like authentication checks, logging, or providing CSRF protection. More information on how Slim handles middleware and how you can even write your own can be found in the Slim documentation.

In our case we will be hooking into Slim’s error handler, catching Errors and Exceptions, and giving a nicely formatted view to you the developer. Let’s get started.

Installation and setup.

Let’s start by installing this middleware with Composer.

$ composer require zeuxisoo/slim-whoops

There are two configurations settings that we need to add to our settings.php file. One tells Whoops! whether to show errors the other is which editor to use to open a file from the stack trace. Available built-in editors are sublime, phpstorm, emacs, textmate, or macvim. I usually put these right under the setting for displayErrorDetails, just to keep things organized.

'debug'         => ('true' === getenv('DEBUG_DETAIL')),
'whoops.editor' => 'phpstorm',

You may have noticed that debug duplicates the displayErrorDetails settings. Although I usually abhor duplication in my code this instance is a necessity. While parts of the Slim core use displayErrorDetails setting, the Whoops! package looks for the debug setting. We’ll have to deal with this one line for now.

The final step will be to add the Whoops library as middleware in our application. Let’s add the following lines to your middleware.php file and then I’ll explain what is going on.

$container = $app->getContainer();

if ($container->get("settings")["displayErrorDetails"]) {
    $app->add(new \Zeuxisoo\Whoops\Provider\Slim\WhoopsMiddleware);
};

The first line gets the container from the application as we have done before. The next thing we will do is check to see if we are displaying errors for this environment. This setting is held in our containers settings as displayErrorDetails. This conditional check is very important as we would not want to show these details to the end-user in, say, a production environment. So, if displayErrorDetails is set to true, such as when we are in a development environment, then we will add the middleware wrapper to the application container. This will make sure that it is called whenever there is an error.

See it in action.

To view an example of a Whoops error dump let’s add a new route that throws an error on purpose.

Open your routes.php file and add a new route before the existing default one.

Why before? Because the default route uses an optional named placeholder that accepts anything after the initial /. If we put our new route after this it will never be reached because the default route acts like a catchall.

Here is our new error route definition.

$app->get('/throw', 'DefaultController:throwException');

Now let’s add a new callback in our default controller for this route to hit. Open DefaultController.php and create a new method called throwException with the following code.

public function throwException(RequestInterface $request, ResponseInterface $response, array $args)
{
    $this->logger->info("Slim-Skeleton '/throw' route");

    throw new \Exception('testing errors 1.2.3..');
}

Here we are doing nothing more than logging the fact that we are here to the message log, and then throwing a PHP Exception for Whoops to catch. Browsing to http://0.0.0.0:8080/throw will now give us a Whoops error page with lots of useful debug information. This includes not only the stack dump but a highlighted view of the code where the exception was raised along with any environment details.

So now, not only do we now know how to add pretty error handling, but we have also learned how to install a simple piece of middleware. Most middleware is fairly simple to implement. Good middleware maintainers will most certainly have installation documentation with any extra options explained.

Until next time, happy debugging.

Code.

See the final code for this article on Github. 006 Debugging Made Easy