You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel适配全量异常的最低层级异常类选型及实现方案咨询

问题

我正尝试修改App\Exceptions\Handler,要把请求(包含当前URL)传递给所有异常,所以需要找到能用于->renderable()方法类型提示的最低层级异常类。Laravel/Symfony的HttpException只适用于HTTP错误,覆盖不了非HTTP异常;PHP原生的Exception类用getCode()替代getStatusCode()时,HTTP错误和异常的返回值都是“0”。想问有没有符合需求的其他低层级异常类,或者其他实现该需求的方法?

当前代码实现:

public function register()
{
    $this->renderable(function (Exception $exception, $request) {
        $url = $request->fullUrl();
        $status = $exception->getCode();

        Log::warning("Error $status when trying to visit $url. Received the following message: " . $exception->getMessage()); 

        return response()->view("errors.$status", [
            "exception" => $exception
        ], $status);    
    });
}

本地测试路由:

if (app()->environment('local')) {
    Route::get("/exception", function (){
        throw new JsonException; // 选它是因为它是少数不会自动解析为HTTP错误的Laravel异常之一
    });
}

if (app()->environment('local')) {
    Route::get("/fail/{status}", function ($status){
        abort($status);
    });
}
解决方案

方法:区分异常类型处理状态码

不需要更换更低层级的异常类,直接在renderable闭包内区分异常类型,分别获取正确的状态码即可:

  • 对于实现HttpExceptionInterface的Laravel/Symfony HTTP异常,调用getStatusCode()获取标准HTTP状态码
  • 对于其他普通异常,设置默认状态码(如500),或对getCode()返回值做合理性校验(若代码不在100-599范围内,强制使用500)

修改后的代码:

use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;

public function register()
{
    $this->renderable(function (\Throwable $exception, $request) {
        $url = $request->fullUrl();
        
        // 根据异常类型获取正确状态码
        if ($exception instanceof HttpExceptionInterface) {
            $status = $exception->getStatusCode();
        } else {
            // 普通异常优先使用有效状态码,无效则用500兜底
            $status = $exception->getCode() >= 100 && $exception->getCode() <= 599 ? $exception->getCode() : 500;
        }

        Log::warning("Error $status when trying to visit $url. Received the following message: " . $exception->getMessage()); 

        // 避免因视图不存在触发二次异常
        $view = view()->exists("errors.$status") ? "errors.$status" : "errors.500";
        
        return response()->view($view, [
            "exception" => $exception
        ], $status);    
    });
}

补充说明

  • 用\Throwable代替Exception作为类型提示,能覆盖PHP中所有可抛出的错误(如Error类),范围更全面
  • 增加视图存在性判断,防止因缺少对应状态码的视图文件导致新异常
  • 测试验证:访问/fail/403会返回403视图,访问/exception会返回500视图,日志中能正确记录请求URL和状态码

内容的提问来源于stack exchange,提问作者Hashim Aziz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 18:57:05