Developing software in the Real World

Custom error rendering in Slim 4

One of the nice things about Slim 4 is that it’s easier to customise the HTML generated on error without having to worry about the rest of the error handling mechanism. This is because we have separated error rendering from error handling.

Slim’s default ErrorHandler maintains a list of renderers, one for each content-type and will delegate the creation of the error payload (HTML, JSON, XML, etc) to the renderer. Out of the Box, the error hander registers an HtmlErrorRenderer which provides a very basic error display:

Slim4 default error no details

We can also enable the displayErrorDetails setting to view the information about the error:

Slim4 default error with details

Separately, the error handler can log these details to the error log.

Writing a custom HTML renderer

To write a new error renderer, we need to create a classs that implements SLim\Interfaces\ErrorRendererInterface. This interface requires a single method:

We are given the exception that caused this error and have to return the HTML we wish to be displayed.

Let’s create our own HTML error renderer. If you want to play along, my Slim4-Starter project is a good place to start from.

We start with a basic HtmlErrorRenderer, which we’ll store in the src/Error/Renderer directory:

We can do whatever we like in __invoke(). In this case, I have chosen to change the title and message based on the class of the $exception. Slim will show a HttpNotFoundException when the router cannot find a registered route for the request URL, so we can use this to show different text explaining the problem.

We also need to render the HTML itself. This is likely to match the rest of your website’s design, so the implementation of renderHtmlPage() is entirely up to you. I’m sure you can do better than I can though!

Register our renderer

We register our renderer, at the point we add the ErrorMiddleare, which in my case is in config/middleware.php:

Don’t forget to add use App\Error\Renderer\HtmlErrorRenderer; at the top of the file and now the new error renderer will now be used.

This is what our new error page looks like:

Slim4 new error page

Using Whoops for development

When we’re developing, it would be useful to have more information about what’s gone wrong. The whoops error handler can provide this, so let’s add it. Fortunately for us, the hard work has been done already by Zeusis in their zeuxisoo/slim-whoops package, so just install it:

We can now add the WhoopsMiddleare if we are in debug mode:

I’ve triggered it on the DEBUG environment variable, bu too course, you should use whatever method works for you in order to determine when the app is in development mode.

Slim4 whoops error

To sum up

That’s it. Changing the error rendering ensure that your error pages look part of your website and it’s easy to do so. In addition, the technique can also be used to render custom error payloads for APIs by registering error renderers for the error handler’s application/json and application/xml content types.

5 thoughts on “Custom error rendering in Slim 4

  1. Great post.
    You know how to handle error 500, try calling \ HttpInternalServerErrorException but it doesn't work for me

    use Slim\Exception\HttpInternalServerErrorException;
    //
    if ($exception instanceof HttpInternalServerErrorException) {
    $title = "500 that's an error";
    $message = 'there was an error trying to send your message. please try again later';
    //
    }

  2. Good afternoon.
    I am happy to follow and read your blog.
    I follow the news and the development of Slim.

    I worked with Slim 3 for a long time and I really like it.
    With the release of Slim 4, for me at least, I can hardly get used to the new approach. For some reason, it turned out to be difficult for me. But this is a special case. I am sure that for the majority this is a pleasant update.

    And Question .. :)
    In your Slim4-Starter, the HomePageHandler.php controller.
    I don't understand how LoggerInterface gets into the constructor.

    Is this autowiring possible?

Thoughts? Leave a reply

Your email address will not be published. Required fields are marked *