laravel 11 中 api 异常必须显式拦截,首选 $request->expectsjson() 判断,推荐组合 || $request->is('api/*') 提升兼容性;自定义异常应实现 responsable 接口并在 toresponse() 中返回标准 json;验证失败宜在 formrequest 的 failedvalidation() 中统一处理。

在 Laravel 11 中,异常渲染机制延续了核心逻辑,但强化了可配置性与类型安全,尤其在 API 响应统一性和错误页面定制上更清晰、更不易出错。关键变化不在于“重写规则”,而在于“默认更合理、扩展更明确”。
API 异常必须显式拦截,旧版也一样,但 Laravel 11 更强调请求识别可靠性
无论 Laravel 10 还是 11,Handler::render() 对 API 请求不做自动 JSON 封装——这是共识,不是版本差异。真正影响效果的是判断方式:
-
$request->expectsJson() 仍是首选:它检查
Accept: application/json或X-Requested-With: XMLHttpRequest,兼容 Axios、Fetch、Postman,浏览器直输 URL 则不触发,逻辑严谨 - Laravel 11 并未废弃
$request->is('api/*'),但文档更明确提醒:单靠 URL 前缀会漏判子域名(如v2.api.example.com)或无前缀的 GraphQL 接口 - 推荐组合写法保持兼容:
if ($request->expectsJson() || $request->is('api/*')) { ... }
自定义异常类写法更规范,Laravel 11 鼓励实现 Responsable 接口
旧版常见写法是仅继承 Exception,在 Handler::render() 里手动判断并返回 JSON;Laravel 11 官方示例和生成命令(php artisan make:exception)默认引导你实现 Responsable 接口:
- 接口要求定义
toResponse(Request $request): Response方法,把响应构造逻辑收归异常自身,控制器和 Handler 都无需重复处理 - 例如
BusinessException可直接返回标准结构:
return response()->json(['code' => $this->code, 'message' => $this->message], $this->statusCode); - 抛出时直接
throw new BusinessException('库存不足', 409, 20301);,Handler 中只需一行判断:
if ($exception instanceof Responsable) { return $exception->toResponse($request); }
验证失败响应控制权更集中,不再依赖中间件或全局 render
表单验证失败默认仍走 ValidationException,但 Laravel 11 进一步明确:最干净的接管点是请求类自身的 failedValidation() 方法:
- 在
FormRequest子类中覆盖该方法,可立即返回任意 JSON 结构,比如带success: false和嵌套errors字段 - 避免在
Handler::render()中二次处理ValidationException,减少逻辑分散 - 若需全局统一格式,可在
failedValidation中抛出一个自定义HttpResponseException,再由 Handler 统一兜底,而非每个请求类都重复构造
错误页面仍靠 resources/views/errors,但 Laravel 11 的 fallback 更可控
Blade 错误页机制没变:404.blade.php、500.blade.php 等仍放在 resources/views/errors/ 下,Laravel 自动匹配。区别在于:
- 当
APP_DEBUG=false且未找到对应视图时,Laravel 11 默认返回更简洁的纯文本错误(如 “Whoops, looks like something went wrong.”),不再尝试渲染通用模板 - 这意味着你必须显式提供
404.blade.php和500.blade.php,否则用户看到的是极简提示,而非空白页或报错堆栈 - 测试时用
abort(404)或访问不存在路由即可验证,无需改环境变量











