Search code examples
phpslim-3

Slim Framework shared exception handler


For each route in my Slim 3 API I have something like the following:

$app->get('/login', function(Request $request, Response $response)
{
  try
  {
    # SOME MAGIC HERE
    # ...
  }
  catch(\My\ExpectedParamException $e)
  {
    $response->withStatus(400); # bad request
  }
  catch(\My\ExpectedResultException $e)
  {
    $response->withStatus(401); # unauthorized
  }
  catch(Exception $e)
  {
    $this->logger->write($e->getMessage());
    throw $e;
  }
});

I would write this pattern just once, to avoid code redundancy as much as possible. Basically my routes definition should be limited to #SOME MAGIC HERE. Does Slim provide a way to catch errors in just one part of the code?


Solution

  • Yes, you can handle all scenarios in one place. Just define your own error handler and pass it to DI container:

    $container = new \Slim\Container();
    $container['errorHandler'] = function ($container) {
        return function ($request, $response, $exception) use ($container) {
            if ($exception instanceof \My\ExpectedParamException) {
                return $container['response']->withStatus(400); # bad request
            } elseif ($exception instanceof \My\ExpectedResultException) {
                return $container['response']->withStatus(400); # unauthorized
            }
            return $container['response']->withStatus(500)
                                 ->withHeader('Content-Type', 'text/html')
                                 ->write('Something went wrong!');
        };
    };
    $app = new \Slim\App($container);
    

    Have a look at corresponding part of the framework documentation.