# 異常處理器 在 `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 ```