I'm migrating from Slim/3 to Slim/4. I've found or figured out replacements for all the features I was using that have been removed, except 404 Not Found Handler (part of the now gone App::$settings
):
Slim
App::$settings
have been removed, multiple middleware have been implemented to replace the functionality from each individual settings.
Is there a middleware for notFoundHandler
? If there isn't, how can I implement it?
Mine used to look like this:
use Slim\Container;
$config = new Container();
$config['notFoundHandler'] = function (Container $c) {
return function (Request $request, Response $response) use ($c): Response {
$page = new Alvaro\Pages\Error($c);
return $page->notFound404($request, $response);
};
};
According to Slim 4 documentation on error handling
Each Slim Framework application has an error handler that receives all uncaught PHP exceptions
You can set a custom error handler to handle each type of exceptions thrown. A list of predefined exception classes is available on same page.
Here is a very basic example of how to register a closure as an error handler, to handle only HttpNotFoundException
exceptions. You can also put the handler in a class that extends Slim\Handlers\ErrorHandler
. Also, I did not actually use your Alvaro\Pages\Error
to generate the response, but changing it should be straightforward:
<?php
require '../vendor/autoload.php';
$app = Slim\Factory\AppFactory::create();
// Define Custom Error Handler
$customErrorHandler = function (
Psr\Http\Message\ServerRequestInterface $request,
\Throwable $exception,
bool $displayErrorDetails,
bool $logErrors,
bool $logErrorDetails
) use ($app) {
$response = $app->getResponseFactory()->createResponse();
// seems the followin can be replaced by your custom response
// $page = new Alvaro\Pages\Error($c);
// return $page->notFound404($request, $response);
$response->getBody()->write('not found');
return $response->withStatus(404);
};
// Add Error Middleware
$errorMiddleware = $app->addErrorMiddleware(true, true, true);
// Register the handler to handle only HttpNotFoundException
// Changing the first parameter registers the error handler for other types of exceptions
$errorMiddleware->setErrorHandler(Slim\Exception\HttpNotFoundException::class, $customErrorHandler);
$app->get('/', function ($request, $response) {
$response->getBody()->write('Hello Slim 4');
return $response;
});
$app->run();
Another approach is to create a generic error handler and register it as the default handler, and inside that handler, decide what response should be sent based on type of exception that is thrown. Something like:
$customErrorHandler = function (
Psr\Http\Message\ServerRequestInterface $request,
\Throwable $exception,
bool $displayErrorDetails,
bool $logErrors,
bool $logErrorDetails
) use ($app) {
$response = $app->getResponseFactory()->createResponse();
if ($exception instanceof HttpNotFoundException) {
$message = 'not found';
$code = 404;
} elseif ($exception instanceof HttpMethodNotAllowedException) {
$message = 'not allowed';
$code = 403;
}
// ...other status codes, messages, or generally other responses for other types of exceptions
$response->getBody()->write($message);
return $response->withStatus($code);
};
Then you can set this as the default error handler:
$errorMiddleware = $app->addErrorMiddleware(true, true, true);
$errorMiddleware->setDefaultErrorHandler($customErrorHandler);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With