# 异常处理器 在 `Hyperf` 里,业务代码都运行在 `Worker 进程` 上,也就意味着一旦任意一个请求的业务存在没有捕获处理的异常的话,都会导致对应的 `Worker 进程` 被中断退出,这对服务而言也是不能接受的,捕获异常并输出合理的报错内容给客户端也是更加友好的。 我们可以通过对各个 `server` 定义不同的 `异常处理器(ExceptionHandler)`,一旦业务流程存在没有捕获的异常,都会被传递到已注册的 `异常处理器(ExceptionHandler)` 去处理。 ## 自定义一个异常处理 ### 注册异常处理器 目前仅支持配置文件的形式注册 `异常处理器(ExceptionHandler)`,配置文件位于 `config/autoload/exceptions.php`,将您的自定义异常处理器配置在对应的 `server` 下即可: ```php [ // 这里的 http 对应 config/autoload/server.php 内的 server 所对应的 name 值 'http' => [ // 这里配置完整的类命名空间地址已完成对该异常处理器的注册 \App\Exception\Handler\FooExceptionHandler::class, ], ], ]; ``` > 每个异常处理器配置数组的顺序决定了异常在处理器间传递的顺序。 ### 定义异常处理器 我们可以在任意位置定义一个 `类(Class)` 并继承抽象类 ` Hyperf\ExceptionHandler\ExceptionHandler` 并实现其中的抽象方法,如下: ```php $throwable->getCode(), 'message' => $throwable->getMessage(), ], JSON_UNESCAPED_UNICODE); // 阻止异常冒泡 $this->stopPropagation(); return $response->withStatus(500)->withBody(new SwooleStream($data)); } // 交给下一个异常处理器 return $response; // 或者不做处理直接屏蔽异常 } /** * 判断该异常处理器是否要对该异常进行处理 */ public function isValid(Throwable $throwable): bool { return true; } } ``` ### 定义异常类 ```php stopPropagation()` 则不再往后传递,若最后一个配置的异常处理器仍不对该异常进行捕获处理,那么就会交由 Hyperf 的默认异常处理器处理了。 ## 集成 Whoops 框架提供了 Whoops 集成。 首先安装 Whoops ```php composer require --dev filp/whoops ``` 然后配置 Whoops 专用异常处理器。 ```php // config/autoload/exceptions.php return [ 'handler' => [ 'http' => [ \Hyperf\ExceptionHandler\Handler\WhoopsExceptionHandler::class, ], ], ]; ``` 效果如图: ![whoops](/imgs/whoops.png) ## Error 监听器 框架提供了 `error_reporting()` 错误级别的监听器 `Hyperf\ExceptionHandler\Listener\ErrorExceptionHandler`。 ### 配置 在 `config/autoload/listeners.php` 中添加监听器 ```php getMessage()); } // string(14) "ErrorException" // string(19) "Undefined offset: 1" ``` 如果不配置监听器则如下,且不会抛出异常。 ``` PHP Notice: Undefined offset: 1 in IndexController.php on line 24 Notice: Undefined offset: 1 in IndexController.php on line 24 NULL ```