Hello.
Although I like the current psr-15 standard, I’ve realized that a third 
interface for http errors could be useful. I’m not sure whether this has been 
discussed before, just drop it here just in case you consider it interesting.

Currently is easy to pass values from outer middlewares to inner middlewares, 
thanks to the server request attributes, but not the opossite, due there’s no 
response attributes. This is ok because there should be not need to pass values 
in reverse order, with the exception of errors. When an error occurs, usually 
is handled throwing a exception to be catched in a outer middleware. This 
approach has some limitations:
- There’s no (standard) way to decide whether the exception produces a 500 
code, 404, 405, etc… This decision is made by the error handler.
- There’s no way to get context data for loggin purposes.

So I’d like to propose a new HttpErrorException to fix these issues. When an 
error handler catches a HttpErrorException, it knows what type of error is, 
because there’s the $exception->getCode() and $exception->getMessage() (that 
should be the status code and reason phrase). If the error is generated because 
other exception (p.e. PDOException), it can be retrieved using 
$exception->getPrevious(). And we could add the methods 
$exception->setContext() and $exception->getContext() to retrieve the context 
data to use it in a PSR-3 logger. Let’s see an example:


class ErrorHandler implements MiddlewareInterface
{
    public function process(ServerRequestInterface $request, DelegateInterface 
$delegate)
    {
        try {
            $response = $delegate->process($request);
        } catch (HttpErrorException $exception) {
            //Log
            $this->logger->error('Http Error', [
                'context' => $exception->getContext(),
                'exception' => $exception->getPrevious() ?: $exception
            ]);

            //Create and return the response
            $response = $this->factory->createResponse($exception->getCode());
            $response->getBody()->write($exception->getMessage());

            return $response;
        } catch (Exception $exception) {
            //Log
            $this->logger->error('Exception', ['exception' => $exception]);

            //Generic error 500
            $response = $this->factory->createResponse(500);
            $response->getBody()->write('Server error');

            return $response;
        }

        return $response;
    }
}

Something like this is used in Zend Expresive 
(https://zendframework.com/blog/2017-03-23-expressive-error-handling.html 
<https://zendframework.com/blog/2017-03-23-expressive-error-handling.html>), 
https://github.com/middlewares/error-handler 
<https://github.com/middlewares/error-handler>, etc. I think it’s a good idea 
to create an interface that can be used by any middleware instead create 
vendor-specific exceptions. This allows to have an error handler that can 
understand any error and handle it correctly.


-- 
You received this message because you are subscribed to the Google Groups "PHP 
Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/php-fig/AD782EAE-00D2-4D01-BFE9-476427080DEB%40gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to