I tried to upload a file to a location that didn’t exist and my app died. I want to handle a situation like this so that a nice JSON error message is returned explaining what went wrong.
I created an HttpExceptionMiddleware class and included my Responder: use App\Responder\Responder;
In the process method I tried returning the responder like so: return $this->responder->withJson($response, $responseData);
In config/middleware: $app->add(HttpExceptionMiddleware::class);
In my container:
// For the responder
ResponseFactoryInterface::class => function (ContainerInterface $container) {
return $container->get(App::class)->getResponseFactory();
},
<?php
namespace App\Middleware;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Slim\Exception\HttpException;
use App\Responder\Responder;
final class HttpExceptionMiddleware implements MiddlewareInterface
{
/*
*
* @var ResponseFactoryInterface
*/
private $responseFactory;
/**
* @var Responder
*/
private $responder;
public function __construct(ResponseFactoryInterface $responseFactory, Responder $responder)
{
$this->responseFactory = $responseFactory;
$this->responder = $responder;
}
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface {
try {
return $handler->handle($request);
} catch (HttpException $httpException) {
// Handle the http exception here
$statusCode = $httpException->getCode();
$response = $this->responseFactory->createResponse()->withStatus($statusCode);
$errorMessage = sprintf('%s %s', $statusCode, $response->getReasonPhrase());
$responseData = [
'errorMessage' => $errorMessage
]
// Log the error message //
//$this->logger->error($errorMessage);
// Render twig template or just add the content to the body
//$response->getBody()->write($errorMessage);
// Invoke the Responder and pass in the response and data ($result)
return $this->responder->withJson($response, $responseData);
//return $response;
}
}
}
The HttpExceptionMiddleware looks good, but it can only catch Slim\Exception\HttpException Exceptions and not other types of PHP or custom Exceptions. If you want to handle all errors you may try to catch Throwable or Exception instead.