-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Slim 4 - How to handle errors by ourselves completely? #2757
Comments
By calling the In Slim 4 you could either define your custom error handler (and pass it to the More information can be found in the docs, currently in development: https://github.com/slimphp/Slim-Website/blob/gh-pages-4.x/docs/v4/middleware/error-handling.md |
@adriansuter none of that actually works. giving up... In my view, this should be made simpler. But it is way too complicated now. |
@lautiamkok it does work, I think you're doing something wrong on your end. Where are you adding this middleware? It should be the very last middleware you add, right before that middleware should be the routing middleware, otherwise Slim automatically appends the |
@l0gicgate let me check later again and get back to you later. there are some errors in the code in the doc by the way slim should have left all the error handling alone from the year dot. how it handles errors just does not make sense. for example in slim 3.12, if i want to handle 404 and other errors myself, I have to write two blocks of code:
It should just be one block of code. also, |
My personal view on these lines below for handling error in slim 4:
I am not sure if this is a PSR standard or not but it is too ugly to read and to understand what is going on. I don't know what these two this is just my opinion. |
That is dependency injection. As the middleware needs to have the callable resolver and the response factory, they would be given to the middleware. That way, the middleware is as independent as possible from the rest. |
I’m closing this as resolved. The docs are clear. If you dislike the architecture you can always use a different framework. You’re also more than welcome to contribute when those architecture decisions are being made, the PRs and discussions are public. |
Another way to handle this is to define a default route after all your other route definitions: $app->any('{route:.*}', function(Request $request, Response $response) {
$response = $response->withStatus(404, 'page not found');
return $response;
}); |
I think a good answer would be to show exactly how a way to disable ALL error handling of any kind since I'm sure slim is already using specific exception types internally that can easily be caught. Or show how to specify a single error handler for all events so a controller view can be used and just display a 404/500 or whatever else message it needs to show accordingly. Just saying docs are clear with no reference and if you don't like it move along isn't a great response. If there is no way to do this I'd agree it is just too complicated. Error handling is so simple. |
I'm unsuccessfully searching for a way to achieve what was so easily possible in Slim 3 – catching any kind of exception caused when calling a route, handling it myself and then displaying a JSON response with a custom HTTP status code, like mentioned in #2757 (comment). Could anybody please point me into the right direction, it's crazy that this standard feature is not even mentioned in the docs. Thanks. |
@skizzo It is possible. Just don't add the ErrorHandlingMiddleware and replace it with your own middleware that catches all Throwables and/or other more specific Exceptions. |
@odan , sorry but your "now draw the rest of the f***king owl" answer is not helpful at all. The issue subject literally says "how" and not "if" this is possible, and nobody here even bothered. So in any case anybody else stumbles over this issue after hours of searching the web (for something that should be properly documented in the first place), I finally got it working like this in Slim Step 1: Install a PSR-7 ImplementationWe need to install a PSR-7 implementation, e.g. Step 2: Create custom Error Handleruse Nyholm\Psr7\Factory\Psr17Factory;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Interfaces\ErrorHandlerInterface;
class NBSlimErrorHandler implements ErrorHandlerInterface
{
// invoked from outside of Slim
public static function logException(Throwable $exception)
{
$statusCode = 500; // or anything else
$errorData = NBSlimErrorHandler::getExceptionData($exception);
// feel free to use your own logger here
NBLogger::error($errorData["message"], [
"message" => $errorData["message"],
"file" => $errorData["file"],
"line" => $errorData["line"],
"trace" => $errorData["trace"],
]);
header('Content-Type: application/json');
http_response_code(500);
echo json_encode([
"success" => false,
"error" => $errorData,
]);
exit();
}
// invoked by Slim
public function __invoke(ServerRequestInterface $request, Throwable $exception, bool $displayErrorDetails, bool $logErrors, bool $logErrorDetails): ResponseInterface
{
$statusCode = 500; // or anything else
$errorData = NBSlimErrorHandler::getExceptionData($exception);
// feel free to use your own logger here
NBLogger::error($errorData["message"], [
"message" => $errorData["message"],
"file" => $errorData["file"],
"line" => $errorData["line"],
"trace" => $errorData["trace"],
]);
$psr17Factory = new Psr17Factory();
$response = $psr17Factory->createResponse($statusCode);
$response->getBody()->write(json_encode([
"success" => false,
"error" => $errorData,
]));
return $response->withStatus($statusCode)->withHeader('Content-Type', 'application/json');
}
// Helper Function to extract data from an exception
public static function getExceptionData(Throwable $exception)
{
$stripPath = getPublicHtmlFolder(); // see below
$message = $exception->getMessage();
$file = implode("", explode($stripPath, $exception->getFile())); // remove $stripPath
$line = $exception->getLine();
$trace = $exception->getTraceAsString();
$trace = explode("\n", substr(implode("", explode($stripPath, $trace)), 1));
return [
"message" => $message,
"file" => $file,
"line" => $line,
"trace" => $trace,
];
}
}
// for errors outside of a Slim Route handler
function log_exception(Throwable $exception)
{
NBSlimErrorHandler::logException($exception);
}
set_exception_handler("log_exception");
ini_set("display_errors", "off");
error_reporting(E_ALL);
// helper function to determine the public_html folder
function getPublicHtmlFolder()
{
$dirname = dirname(__DIR__);
$search = "/public_html/";
$pathPublicHtml = mb_substr($dirname, 0, mb_strpos($dirname, $search) + mb_strlen($search));
return $pathPublicHtml;
} Step 3: Use custom Error Handler in Slim App// ...
$app = AppFactory::create();
$app->setBasePath("/your/base/path");
// Use custom Error Handler
$errorMiddleware = $app->addErrorMiddleware(true, true, true);
$errorMiddleware->setDefaultErrorHandler(NBSlimErrorHandler::class);
// Add Routing Middleware
$app->addRoutingMiddleware();
// ... |
|
I apologize for my tone, but it's just frustrating that issues like these are being closed with reasoning that sounds like "RTFM" when the docs obviously don't explain such a basic use case scenario – which is why this issue was created in the first place. |
I get your frustration @skizzo. If its so clear then why is it so hard for anyone to say it. Thanks for posting your solution im sure it will help someone. Feel bad for not posting what I did to resolve this now. |
@skizzo |
How can we handle errors by ourselves completely?
I get this error below:
If I remove these lines:
Then, when we try to catch to the error through a middleware:
We get the same error back:
We are trying to make our custom error in the JSON format, for example:
{"status":404,"message":"page not found"}
Any ideas?
The text was updated successfully, but these errors were encountered: