背景:
在使用swoft做API接口时候,当出现错误抛出异常时往往格式并不是我们需要的,正常来说我们需要的是类似于我们接口统一返回的格式,这种情况下我们需要自定义异常类去处理抛出异常的数据格式。
步骤:
1、swoft的异常类通常放在app/Exception 目录下,需要定义一个异常类和一个异常处理类,异常类和框架原来的定义的一样都是定义一个类基础Exception类即可。
<?php namespace AppException; class ApiException extends Exception { }
2、异常处理类定义在app/Exception/Hander 目录下,定义一个Handler类,然后继承 AbstractHttpErrorHandler!这里只要注意的是注解部分的 @
ExceptionHandler(用于捕获并统一异常!在出错时不用到处捕获异常而是在这里会统一处理,参数为异常类)
<?php declare(strict_types=1); /** * This file is part of Swoft. * * @link https://swoft.org * @document https://swoft.org/docs * @contact group@swoft.org * @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE */ namespace AppExceptionHandler; use AppExceptionApiException; use SwoftErrorAnnotationMappingExceptionHandler; use SwoftHttpMessageResponse; use SwoftHttpServerExceptionHandlerAbstractHttpErrorHandler; use Throwable; /** * Class ApiExceptionHandler * * @since 2.0 * * @ExceptionHandler(ApiException::class) */ class ApiExceptionHandler extends AbstractHttpErrorHandler { /** * @param Throwable $except * @param Response $response * * @return Response */ public function handle(Throwable $except, Response $response): Response { $data = [ 'code' => $except->getCode(), 'msg' => sprintf('(%s) %s', get_class($except), $except->getMessage()), 'data' => sprintf('At %s line %d', $except->getFile(), $except->getLine()), ]; return $response->withData($data); } }
统一抛出异常类的好处:
在做项目的时候为了代码逻辑清晰,可以在把代码分层,放到不同的文件处理。如果没有采用这种异常处理方式,就得在调用处捕获异常。例如我在 Controller 层调用了 Service 和 Logic 层,每一层都抛出异常,我们需要在控制器捕获异常,那么我们每次写代码都会带上 try 的代码。使用统一异常处理,我们不再需要再调用处捕获,会自动捕获这个异常并按照开发者的逻辑处理。