和PHP默认的异常处理不同,ThinkPHP抛出的不是单纯的错误信息,而是一个人性化的错误页面。
[TOC=2,2]
## 异常显示
新版的异常页面显示会自动判断当前的请求是否为Json请求,如果是JSON请求则采用JSON格式输出异常信息,否则按照HTML格式输出。
在调试模式下,系统默认展示的异常页面:
![](https://box.kancloud.cn/cc2522ef8a6b4c94f2ca1421619e87ca_736x642.png)
>[info]只有在调试模式下面才能显示具体的错误信息,如果在部署模式下面,你可能看到的是一个简单的提示文字,例如:
![](https://img.kancloud.cn/5c/f8/5cf8baf61164b7a2d2f7e4a56a233273_881x183.png)
你可以通过设置`exception_tmpl`配置参数来自定义你的异常页面模板,默认的异常模板位于:
~~~
thinkphp/tpl/think_exception.tpl
~~~
你可以在应用配置文件`app.php`中更改异常模板
~~~
// 自定义异常页面的模板文件
'exception_tmpl' => \think\facade\App::getAppPath() . 'template/exception.tpl',
~~~
默认的异常页面会返回`500`状态码,如果是一个`HttpException`异常则会返回HTTP的错误状态码。
## 异常处理接管
>[danger] 本着严谨的原则,框架会对任何错误(包括警告错误)抛出异常。系统产生的异常和错误都是程序的隐患,要尽早排除和解决,而不是掩盖。对于应用自己抛出的异常则做出相应的捕获处理。
框架支持异常处理由开发者自定义类进行接管,需要在`app`目录下面的`provider.php`文件中绑定异常处理类,例如:
~~~
// 绑定自定义异常处理handle类
'think\exception\Handle' => '\\app\\exception\\Http',
~~~
自定义类需要继承`think\exception\Handle`并且实现`render`方法,可以参考如下代码:
~~~
<?php
namespace app\common\exception;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\ValidateException;
use think\Response;
use Throwable;
class Http extends Handle
{
public function render($request, Throwable $e): Response
{
// 参数验证错误
if ($e instanceof ValidateException) {
return json($e->getError(), 422);
}
// 请求异常
if ($e instanceof HttpException && $request->isAjax()) {
return response($e->getMessage(), $e->getStatusCode());
}
// 其他错误交给系统处理
return parent::render($request, $e);
}
}
~~~
自定义异常处理的主要作用是根据不同的异常类型发送不同的状态码和响应输出格式。
>[danger] 事实上,默认安装应用后,已经帮你内置了一个`app\ExceptionHandle`异常处理类,直接修改该类的相关方法即可完成应用的自定义异常处理机制。
>[info] 需要注意的是,如果自定义异常处理类没有再次调用系统`render`方法的话,配置`http_exception_template`就不再生效,具体可以参考`Handle`类内实现的功能。
## 手动抛出和捕获异常
ThinkPHP大部分情况异常都是自动抛出和捕获的,你也可以手动使用`throw`来抛出一个异常,例如:
~~~
// 使用think自带异常类抛出异常
throw new \think\Exception('异常消息', 10006);
~~~
手动捕获异常方式是使用`try-catch`,例如:
~~~
try {
// 这里是主体代码
} catch (ValidateException $e) {
// 这是进行验证异常捕获
return json($e->getError());
} catch (\Exception $e) {
// 这是进行异常捕获
return json($e->getMessage());
}
~~~
> 支持使用`try-catch-finally`结构捕获异常。
## HTTP 异常
可以使用`\think\exception\HttpException`类来抛出异常
框架提供了一个`abort`助手函数快速抛出一个HTTP异常:
~~~
<?php
namespace app\index\controller;
class Index
{
public function index()
{
// 抛出 HTTP 异常
throw new \think\exception\HttpException(404, '异常消息');
}
}
~~~
系统提供了助手函数`abort`简化HTTP异常的处理,例如:
框架提供了一个`abort`助手函数快速抛出一个HTTP异常:
~~~
<?php
namespace app\index\controller;
class Index
{
public function index()
{
// 抛出404异常
abort(404, '页面异常');
}
}
~~~
如果你的应用是API接口,那么请注意在客户端首先判断HTTP状态码是否正常,然后再进行数据处理,当遇到错误的状态码的话,应该根据状态码自行给出错误提示,或者采用下面的方法进行自定义异常处理。
**部署模式**下一旦抛出了`HttpException`异常,可以定义单独的异常页面模板,只需要在`app.php`配置文件中增加:
~~~
'http_exception_template' => [
// 定义404错误的模板文件地址
404 => \think\facade\App::getAppPath() . '404.html',
// 还可以定义其它的HTTP status
401 => \think\facade\App::getAppPath() . '401.html',
]
~~~
模板文件支持模板引擎中的标签。
> `http_exception_template`配置仅在部署模式下面生效。
- 序言
- 基础
- 安装
- 开发规范
- 目录结构
- 配置
- 架构
- 请求流程
- 架构总览
- 入口文件
- 多应用模式
- URL访问
- 容器和依赖注入
- 服务
- 门面
- 中间件
- 事件
- 路由
- 路由定义
- 变量规则
- 路由地址
- 路由参数
- 路由中间件
- 路由分组
- 资源路由
- 注解路由
- 路由绑定
- 域名路由
- MISS路由
- 跨域请求
- URL生成
- 控制器
- 控制器定义
- 基础控制器
- 空控制器
- 资源控制器
- 控制器中间件
- 请求
- 请求对象
- 请求信息
- 输入变量
- 请求类型
- HTTP头信息
- 伪静态
- 参数绑定
- 请求缓存
- 响应
- 响应输出
- 响应参数
- 重定向
- 文件下载
- 数据库
- 连接数据库
- 分布式数据库
- 查询构造器
- 查询数据
- 添加数据
- 更新数据
- 删除数据
- 查询表达式
- 链式操作
- where
- table
- alias
- field
- strict
- limit
- page
- order
- group
- having
- join
- union
- distinct
- lock
- cache
- comment
- fetchSql
- force
- partition
- failException
- sequence
- replace
- extra
- duplicate
- procedure
- 聚合查询
- 分页查询
- 时间查询
- 高级查询
- 视图查询
- JSON字段
- 子查询
- 原生查询
- 查询事件
- 获取器
- 事务操作
- 存储过程
- 数据集
- 数据库驱动
- 模型
- 定义
- 模型字段
- 新增
- 更新
- 删除
- 查询
- 查询范围
- JSON字段
- 获取器
- 修改器
- 搜索器
- 数据集
- 自动时间戳
- 只读字段
- 软删除
- 类型转换
- 模型输出
- 模型事件
- 模型关联
- 一对一关联
- 一对多关联
- 远程一对多
- 远程一对一
- 多对多关联
- 多态关联
- 关联预载入
- 关联统计
- 关联输出
- 视图
- 模板变量
- 视图过滤
- 模板渲染
- 模板引擎
- 视图驱动
- 错误和日志
- 异常处理
- 日志处理
- 调试
- 调试模式
- Trace调试
- SQL调试
- 变量调试
- 远程调试
- 验证
- 验证器
- 验证规则
- 错误信息
- 验证场景
- 路由验证
- 内置规则
- 表单令牌
- 注解验证
- 杂项
- 缓存
- Session
- Cookie
- 多语言
- 上传
- 命令行
- 启动内置服务器
- 查看版本
- 自动生成应用目录
- 创建类库文件
- 清除缓存文件
- 生成数据表字段缓存
- 生成路由映射缓存
- 输出路由定义
- 自定义指令
- 扩展库
- 数据库迁移工具
- Workerman
- think助手工具库
- 验证码
- Swoole
- 附录
- 助手函数
- 升级指导
- 更新日志