tp5异常全局返回处理
tp5 针对对异常,在debug模式下,会直接以页面返回的形式显示出各类错误。如果debug关机,显示
页面错误!请稍后再试~
// 注册错误和异常处理机制 Error::register();
self::getExceptionHandler()->render($e)->send()
getExceptionHandler()是判断有没有自定义的异常处理类,如果没有默认使用namespace think\exception\Handle类处理异常(也就是tp5的默认处理方式)。
而我们可以在namespace think\App里的初始化函数定义了一个操作,如果配置里定义了自定义的异常处理类,那么就使用自定义异常处理类。也就是不用Handle类了。
大致思路是这样,我们开始具体操作
首先我在 新建 namespace app\common\exception\ApiHandleException类
<?php /** * Created by PhpStorm. * User: wangjing4 * Date: 2019-12-17 * Time: 9:19 */ namespace app\common\exception; use Exception; use think\exception\Handle; use think\exception\HttpException; use think\exception\ErrorException; use think\exception\PDOException; use think\facade\Log; class ApiHandleException extends Handle { public function render(Exception $e) { if( config('app_debug') ){ return parent::render($e); }else{ $log['apiError'] = $this->getApiError($e); $log['getData'] = $_GET; $log['postData'] = $_POST; $log['headerData'] = $_SERVER; $re = $this->recordErrorLog($log); if ($e instanceof HttpException) { return json(array('msg'=>'请求错误','code'=> 400)); } if ($e instanceof ErrorException) { return json(array('msg'=>'返回异常','code'=> 500)); } if ($e instanceof PDOException) { return json(array('msg'=>"SQL异常",'code'=> 600)); } } } private function getApiError($e){ $data = []; if ($e instanceof HttpException) { $data['msg'] = $e->getMessage(); } if ($e instanceof ErrorException) { $data['msg'] = $e->getMessage(); $data['file'] = $e->getFile(); $data['line'] = $e->getLine(); } if ($e instanceof PDOException) { $data['msg'] = $e->getData('Database Status'); } return $data; } private function recordErrorLog($data) { Log::record($data,'error'); } }
然后在配置文件里定义
'exception_handle' => '\app\common\exception\ApiHandleException',
这样我们自己定义的这个类就接管异常处理了。
具体看下ApiHandleException类的思路。我们启用新的异常处理类,其实最终就是要替换类里的render方法
所以新增render方法。首先ApiHandleException肯定要先继承Handle类。当我们再debug模式的时候,大部分
是我们编写接口的使用用postman类工具调试。此时tp5默认的抛出异常页面挺适合我们查看错误的。所以就默认
启用Handle里的render方法。而当上生产的时候,会关闭debug模式。此时我们就可以根据抛出的异常所属类来
返回大致的消息
if ($e instanceof HttpException) { return json(array('msg'=>'请求错误','code'=> 400)); } if ($e instanceof ErrorException) { return json(array('msg'=>'返回异常','code'=> 500)); } if ($e instanceof PDOException) { return json(array('msg'=>"SQL异常",'code'=> 600)); }
这几个异常类型是我自己调试出来的。基本就这三种异常错误。
当你你访问不存在的控制器或者方法的时候是会被 think\exception\HttpException;类抛出。
当页面代码有拼写错误的时候,一般就是会think\exception\ErrorException报500错误。
而当sql语句问题导致的错误会被think\exception\PDOException抛出
生产环境需要记录日志的时候,我使用了tp5的默认日志方法,根据不同报错,保存了每种错误类型的基本信息,确保后端根据日志快速定位问题点。
比如HttpException错误;异常本身的错误提示基本就可以知道问题出在哪了。
而ErrorException可能就要定位到错误文件,错误的行数以及错误的提示语。
当遇到PDOException错误的时候,错误类默认记录的PDO Error Info数据即可帮助我们快速知道错误sql