igniphp / framework

Swoole, PSR-15, PSR-7, PSR-11 lightweight modular anti-framework for REST micro-services.
MIT License
265 stars 14 forks source link

Exception handling #5

Closed lezhnev74 closed 6 years ago

lezhnev74 commented 6 years ago

From the documentation, it is not clear how to handle exception occurred in business logic. Since Swool does not support set_exception_handler function, where is the central error handler in igni framework and what is the preferred way to handle exceptions and provide pretty output to the client?

Thanks!

p.s. I managed to find this ErrorMiddleware which by default catches any exception (and converts errors to exceptions). I guess error handling is something to be done via that middleware, right?

dkraczkowski commented 6 years ago

@lezhnev74 Hello, all thrown and unhandled exceptions in your application are by default handled by\Igni\Http\Middleware\ErrorMiddleware class which returns 500 response with error message provided by the exception.

If you would like to have one central place for all your business exceptions the preferred way is to define psr middleware, for example:

<?php
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

final class MyErrorHandler implements MiddlewareInterface
{
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        try {
            // Allow rest of middleware pipe to do its job
            $response = $next->handle($request);
        }  catch (TheExceptionTypeYouWouldLikeToHandle $exception) {
            $response = <here generate your psr response>;
        }
        return $response;
    }
}

The defined middleware should be also added to your application:

$application->use(new MyErrorHandler());

please also refer to this link

dkraczkowski commented 6 years ago

Optionally you can define your error handler as a closure function and pass it into use method:

$application->use(function(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface {
    try {
        // Allow rest of middleware pipe to do its job
        $response = $next->handle($request);
    }  catch (TheExceptionTypeYouWouldLikeToHandle $exception) {
        $response = <here generate your psr response>;
    }
    return $response;
});
dkraczkowski commented 6 years ago

@lezhnev74 Does it help?

lezhnev74 commented 6 years ago

Yes! Looks clear now. Thank you @dkraczkowski !