tp5 针对对异常,在debug模式下,会直接以页面返回的形式显示出各类错误。如果debug关机,显示
页面错误!请稍后再试~
// 注册错误和异常处理机制 Error::register();
self::getExceptionHandler()->render($e)->send()
getExceptionHandler()是判断有没有自定义的异常处理类,如果没有默认使用namespace thinkexceptionHandle类处理异常(也就是tp5的默认处理方式)。
而我们可以在namespace thinkApp里的初始化函数定义了一个操作,如果配置里定义了自定义的异常处理类,那么就使用自定义异常处理类。也就是不用Handle类了。
大致思路是这样,我们开始具体操作
首先我在 新建 namespace appcommonexceptionApiHandleException类
<?php
/**
* Created by PhpStorm.
* User: wangjing4
* Date: 2019-12-17
* Time: 9:19
*/
namespace appcommonexception;
use Exception;
use thinkexceptionHandle;
use thinkexceptionHttpException;
use thinkexceptionErrorException;
use thinkexceptionPDOException;
use thinkfacadeLog;
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' => 'appcommonexceptionApiHandleException',
这样我们自己定义的这个类就接管异常处理了。
具体看下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));
}
这几个异常类型是我自己调试出来的。基本就这三种异常错误。
当你你访问不存在的控制器或者方法的时候是会被 thinkexceptionHttpException;类抛出。
当页面代码有拼写错误的时候,一般就是会thinkexceptionErrorException报500错误。
而当sql语句问题导致的错误会被thinkexceptionPDOException抛出
生产环境需要记录日志的时候,我使用了tp5的默认日志方法,根据不同报错,保存了每种错误类型的基本信息,确保后端根据日志快速定位问题点。
比如HttpException错误;异常本身的错误提示基本就可以知道问题出在哪了。
而ErrorException可能就要定位到错误文件,错误的行数以及错误的提示语。
当遇到PDOException错误的时候,错误类默认记录的PDO Error Info数据即可帮助我们快速知道错误sql