New to Slim: Creating custom error page

Hi,

I’ve just got started with Slim, looks great so far but I see there’s loads to learn.

I’ve worked my way through this tutorial and got it all working:

Now I want to try doing a few things myself. I thought I’d try something easy and create my own error page. I found this tutorial:
https://akrabat.com/custom-error-rendering-in-slim-4/

It didn’t go as well as I hoped.

I created the renderer in:
/src/Error/Renderer/HtmlErrorRenderer.php

My /config/middleware.php:
<?php

use Slim\App;
use Slim\Middleware\ErrorMiddleware;
use Selective\BasePath\BasePathMiddleware;
use App\Error\Renderer\HtmlErrorRenderer;

return function (App $app) {
    // Parse json, form data and xml
    $app->addBodyParsingMiddleware();

    // Add the Slim built-in routing middleware
    $app->addRoutingMiddleware();

    //$app->setBasePath('/');

    $app->add(BasePathMiddleware::class); // <--- here

    // Catch exceptions and errors
  	$app->add(ErrorMiddleware::class);

/*
      // tried the lines below instead of the line above - no luck
	$errorMiddleware = $app->addErrorMiddleware(false, true, true);
    $errorHandler = $errorMiddleware->getDefaultErrorHandler();
    $errorHandler->registerErrorRenderer('text/html', HtmlErrorRenderer::class);
*/
};

I also tried using this code within the container but that didn’t work.

Can anyone help me with this? I’m thinking the container is a better place for this but I couldn’t wrong entirely.

Thank you!

Hi!

Yes, the DI container would be a better place to put together all the dependencies for the “infrastructure” like the error handler, etc.

Search for the ErrorMiddleware::class definition in the container settings file and modifiy it as follows:

ErrorMiddleware::class => function (ContainerInterface $container) {
    $settings = $container->get('settings')['error'];
    $app = $container->get(App::class);

    $errorMiddleware = new ErrorMiddleware(
        $app->getCallableResolver(),
        $app->getResponseFactory(),
        (bool)$settings['display_error_details'],
        (bool)$settings['log_errors'],
        (bool)$settings['log_error_details'],
    );

    $errorHandler = $errorMiddleware->getDefaultErrorHandler();
    $htmlErrorRenderer = $container->get(\App\Error\Renderer\HtmlErrorRenderer::class);
    $errorHandler->registerErrorRenderer('text/html', $htmlErrorRenderer);

    return $errorMiddleware;
},

Please note that is just an example. I have not tested it.

Read more: Slim 4 Error Handling

1 Like

Hi Odan,

Thank you very much for your reply. I figured this out myself before I read your post, the main issue I was having was in the renderer:

final class HtmlErrorRenderer extends ErrorRendererInterface

should be:

final class HtmlErrorRenderer

This is what I ended up with in the DI, this works:

 // at the top of the script
  use App\Error\Renderer\HtmlErrorRenderer;


    ErrorMiddleware::class => function (ContainerInterface $container) {
    $app = $container->get(App::class);
    $settings = $container->get('settings')['error'];

    $errorMiddleware = new ErrorMiddleware(
        $app->getCallableResolver(),
        $app->getResponseFactory(),
        (bool)$settings['display_error_details'],
        (bool)$settings['log_errors'],
        (bool)$settings['log_error_details']
    );

    $errorHandler = $errorMiddleware->getDefaultErrorHandler();
    $errorHandler->registerErrorRenderer('text/html', HtmlErrorRenderer::class);

    return $errorMiddleware;

},

I went one further and added in Whoops too:

    ErrorMiddleware::class => function (ContainerInterface $container) {
    $app = $container->get(App::class);
    $settings = $container->get('settings')['error'];

    $errorMiddleware = new ErrorMiddleware(
        $app->getCallableResolver(),
        $app->getResponseFactory(),
        (bool)$settings['display_error_details'],
        (bool)$settings['log_errors'],
        (bool)$settings['log_error_details']
    );

    $debug = $container->get('settings')['debug'];
    if ((bool)$debug===true) {
        $errorMiddleware = new Zeuxisoo\Whoops\Slim\WhoopsMiddleware(['enable' => true]);
    } else {
        $errorHandler = $errorMiddleware->getDefaultErrorHandler();
        $errorHandler->registerErrorRenderer('text/html', HtmlErrorRenderer::class);
    }

    return $errorMiddleware;

},
1 Like