TP8异常处理需用think\Exception子类,原生Exception绕过捕获;自定义处理器须返回Response实例,404需通过Route::miss()配置,错误页禁用敏感信息输出。

确认框架是否接管异常
在控制器里写一行测试代码:throw new \Exception('手动抛出');。访问该接口,如果看到完整堆栈或白屏,说明框架没接管;如果显示 think_exception.tpl 模板,则已生效。关键点在于:TP8 只捕获继承自 \think\Exception 或其子类的异常,原生 \Exception 会被 PHP 底层直接处理,完全绕过你的自定义逻辑。所有业务代码中必须改用 throw new \think\exception\HttpException(500, '服务异常') 或 throw new \think\exception\ValidateException('验证失败')。
配置自定义异常处理器
推荐新手使用 app/exception.php 全局绑定方式:
- 在项目根目录创建
app/exception.php - 写入以下内容(注意返回值必须是
Response实例):<?php use think\exception\Handle; use think\Response; use Throwable; return function (Throwable $e): Response { if ($e instanceof \think\Exception\HttpException) { $code = $e->getStatusCode(); } else { $code = 500; } return response(view("error/{$code}", ['exception' => $e]), $code); }; - 确保
config/app.php中未设置'exception_handle',否则两者冲突 - 开发环境需关闭
APP_DEBUG = false才会触发自定义页面,调试时默认走框架调试页
让404也走自定义模板
TP8 的 404 不是异常,Route::miss() 是唯一有效入口:
- 打开
route/app.php,在所有路由定义之后添加:Route::miss(function () { return response()->view('error/404', [], 404); }); - 检查
config/app.php中'url_route_must' => true是否启用,不开启可能导致 404 不被捕获 - 在
app/view/error/下创建404.html或404.php,内容可为:<h1>404 页面不存在</h1>
安全渲染错误页面
模板中严禁输出敏感信息:
立即学习“PHP免费学习笔记(深入)”;
- 生产环境禁止直接使用
$exception->getMessage()或$exception->getTraceAsString() - 只在
APP_DEBUG = true时展示详细错误,否则统一显示“系统繁忙,请稍后再试” - 日志记录应调用
log()->error('Uncaught exception', ['exception' => $e]),而非写进模板 - 模板可安全使用的变量仅限:
$code(状态码)、静态提示文案、时间戳等脱敏数据



















