异常捕获 ExceptionCaptor
Fluff 在发生异常时会直接抛出错误,如果你希望在发生异常时输出一个错误页面,或提示信息,就要使用 ExceptionCaptor
中间件。
添加一个异常处理
use ConstanzeStandard\Fluff\Application;
use ConstanzeStandard\Fluff\Exception\NotFoundException;
use ConstanzeStandard\Fluff\Middleware\EndOutputBuffer;
use ConstanzeStandard\Fluff\Middleware\ExceptionCaptor;
use Nyholm\Psr7\Response;
use Psr\Http\Message\ServerRequestInterface;
...
$notFoundHandler = function(ServerRequestInterface $request, \Throwable $e) {
return new Response(404, [], $e->getMessage());
};
/** @var ExceptionCaptor $exceptionCaptor */
$exceptionCaptor = $app->addMiddleware(new ExceptionCaptor());
$exceptionCaptor->withExceptionHandler(NotFoundException::class, $notFoundHandler);
$app->addMiddleware(new EndOutputBuffer());
上面的例子中,我们为 ConstanzeStandard\Fluff\Exception\NotFoundException
添加了异常处理,当请求没有路由匹配时,就会执行$notFoundHandler
, 并发送 Response
的内容到前端。withExceptionHandler
方法接受两个参数,按参数顺序分别为:
- 异常类型的字符串。
- 异常处理程序。
通过 withExceptionHandler
方法添加一个异常的处理程序,ExceptionCaptor
会向异常的处理程序中传入两个参数,按参数顺序分别为:
- 一个
Psr\Http\Message\ServerRequestInterface
的实例,就是引发异常时的 server request 对象。 - 当前发生的异常对象对象。
当异常发生时,ExceptionCaptor
会首先查找注册过的,与当前异常类型一致的处理程序,如果没有,则会继续检查是否注册过当前异常类型的父级类型,如果存在,则执行对应的处理程序,并返回处理程序提供的 Psr\Http\Message\ResponseInterface
实例;如果不存在处理程序,则会直接抛出异常。
所以,如果你想定义一个应对所有异常的处理程序,那就是 \Exception
类型的处理程序。
ExceptionCaptor
中间件需要在 EndOutputBuffer
的内层,因为它需要 EndOutputBuffer 输出 Response
的内容。所以在代码中,ExceptionCaptor
应该在 EndOutputBuffer
之前添加进 Application
.
将 Error 转化为 Exception
ExceptionCaptor
只适合捕获异常,如果想捕获 Error,我们可以将 Error 转化为 Exception. 这段程序由 php manual 提供
use ErrorException;
set_error_handler(function ($severity, $message, $file, $line) {
if (!(error_reporting() & $severity)) {
// This error code is not included in error_reporting
return;
}
throw new ErrorException($message, 0, $severity, $file, $line);
});