ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
异常捕捉 异常捕捉(看云文档)内容挺多的,自己去百度吧,我就把我遇到过的常见的错误进行捕捉,其它的异常我也爱莫能助,不懂啊 !>_>! 我也就不自定义类了,直接在它给的默认的异常处理文件里写了。 ![](https://img.kancloud.cn/b8/db/b8dbd50d41a1eb5bda7f4f62260e8438_320x464.png) (1)参数验证错误捕捉 我们先写一个参数验证的类,在app目录下创建validate目录,创建User.php文件 app/validate/User.php ``` <?php namespace app\validate; use think\Validate; class User extends Validate { protected $rule = [ 'name' => 'require|max:25', 'age' => 'number|between:1,120', 'email' => 'email', ]; protected $message = [ 'name.require' => '名称必须', 'name.max' => '名称最多不能超过25个字符', 'age.number' => '年龄必须是数字', 'age.between' => '年龄只能在1-120之间', 'email' => '邮箱格式错误', ]; } ``` tp6的异常捕捉分为两种,自动和手动的,手动的就是通过try{}catch{}捕捉。tp6的异常捕捉大多是自动的,不过,比如我们现在要操作的参数验证错误就需要自己去捕捉来抛出异常,我们此节的目的是统一捕捉这个错误,我就不用手动的了。 我们就在异常处理类的render方法中添加这个捕捉抛出就可以了。 ![](https://img.kancloud.cn/dc/a3/dca342b119c5a60e00ea407a4904664c_951x481.png) ``` // 1.参数验证错误 if ($e instanceof ValidateException) { return result($e->getError(), '参数验证不通过', 422); } ``` 现在在方法中一下,看看能否捕获。 app/controller/v1/User.php ![](https://img.kancloud.cn/f1/a7/f1a7e5a77c43468c18f57d9235f81783_913x624.png) 查看结果,成功被捕获到了,并抛出了错误内容 ![](https://img.kancloud.cn/40/0b/400bc6915376065748ce283039118698_725x503.png) 如果验证通过了,就会正常的走下去,则会显示我return的测试内容 ![](https://img.kancloud.cn/f3/c1/f3c1d3cff1df856b5b66006053adda48_829x443.png) (2)未匹配到资源或方法的异常捕获 我还没找到方法,在我的预想中这个应该要做到能够准确的反应未匹配到的原因。 ``` // 2.方法(控制器、路由、http请求)、资源(多媒体文件,如视频、文件)未匹配到, // 一旦在定义的路由规则中匹配不到,它就会直接去匹配控制器,但是因为在控制器中做了版本控制v1,v2这样的,所以它是无法获取对应控制器的 // 所以都会直接走了HttpException的错误 // 感觉好像也无所谓,反正是做api接口的,只不过这样就不好准确的提示信息了 // 到底这个请求时控制器找不到呢?还是方法找不到?还是请求类型(get,post)不对? if(($e instanceof ClassNotFoundException || $e instanceof RouteNotFoundException) || ($e instanceof HttpException && $e->getStatusCode()==404)){ $data = [ 'err_msg' => $e -> getMessage(), 'tips_1' => '请检查路径是否是否填写正确', 'tips_2' => '请检查请求类型是否正确', ]; return result($data, '方法或资源未找到,请检查', 404); } ``` #### 下面就不写了,太麻烦了,直接放全部代码 ``` <?php namespace app; use ParseError; // 语法错误 use TypeError; use InvalidArgumentException; // 参数错误 use think\db\exception\DataNotFoundException; use think\db\exception\ModelNotFoundException; use think\db\exception\PDOException; // 数据库连接错误 use think\db\exception\DbException; // 数据库模型访问错误,比如方法不存在 use think\exception\RouteNotFoundException; use think\exception\ClassNotFoundException; use think\exception\FuncNotFoundException; use think\exception\FileException; use think\exception\Handle; use think\exception\HttpException; use think\exception\HttpResponseException; use think\exception\ValidateException; use think\exception\ErrorException; use think\Response; use Throwable; /** * 应用异常处理类 */ class ExceptionHandle extends Handle { /** * 不需要记录信息(日志)的异常类列表 * @var array */ protected $ignoreReport = [ HttpException::class, HttpResponseException::class, ModelNotFoundException::class, DataNotFoundException::class, ValidateException::class, ]; /** * 记录异常信息(包括日志或者其它方式记录) * * @access public * @param Throwable $exception * @return void */ public function report(Throwable $exception): void { // 使用内置的方式记录异常日志 parent::report($exception); } /** * Render an exception into an HTTP response. * * @access public * @param \think\Request $request * @param Throwable $e * @return Response */ public function render($request, Throwable $e): Response { // 添加自定义异常处理机制 // 请求异常 if ($e instanceof HttpException && $request->isAjax()) { return response($e->getMessage(), $e->getStatusCode()); } // 使用了错误的数据类型 或 缺失参数 if ($e instanceof InvalidArgumentException || $e instanceof ErrorException) { $fileUrlArr = explode(DIRECTORY_SEPARATOR, $e->getFile()); $data = [ 'err_msg' => $e->getMessage(), 'file' => $fileUrlArr[count($fileUrlArr) - 1], 'line' => $e->getLine() ]; return result($data, '参数错误', 413); } // 1.参数验证错误 if ($e instanceof ValidateException) { return result($e->getError(), '参数验证不通过', 422); } // 2.方法(控制器、路由、http请求)、资源(多媒体文件,如视频、文件)未匹配到, // 一旦在定义的路由规则中匹配不到,它就会直接去匹配控制器,但是因为在控制器中做了版本控制v1,v2这样的,所以它是无法获取对应控制器的 // 所以都会直接走了HttpException的错误 // 感觉好像也无所谓,反正是做api接口的,只不过这样就不好准确的提示信息了 // 到底这个请求时控制器找不到呢?还是方法找不到?还是请求类型(get,post)不对? if(($e instanceof ClassNotFoundException || $e instanceof RouteNotFoundException) || ($e instanceof HttpException && $e->getStatusCode()==404)){ $data = [ 'err_msg' => $e -> getMessage(), 'tip_1' => '请检查路径是否是否填写正确', 'tips_2' => '请检查请求类型是否正确', ]; return result($data, '方法或资源未找到,请检查', 404); } // 3.语法错误 if ($e instanceof ParseError) { $fileUrlArr = explode(DIRECTORY_SEPARATOR, $e->getFile()); $data = [ 'err_msg' => $e->getMessage(), 'file' => $fileUrlArr[count($fileUrlArr) - 1], 'line' => $e->getLine() ]; return result($data, '服务器异常-语法错误', 411); } // 4.数据库错误 if ($e instanceof PDOException || $e instanceof DbException) { $fileUrlArr = explode(DIRECTORY_SEPARATOR, $e->getFile()); $data = [ 'err_msg' => $e->getMessage(), 'file' => $fileUrlArr[count($fileUrlArr) - 1], 'line' => $e->getLine() ]; return result($data, '服务器异常-数据库错误', 412); } // 其他错误交给系统处理 return parent::render($request, $e); } } ```