Laravel 全局异常捕获


Laravel 带有一个内置的异常处理程序,可以让您轻松地以友好的方式报告和呈现异常。

 Laravel 中默认的异常处理类  app/Exceptions/Handler.php 文件

<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;

class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that are not reported.
     *
     * @var array
     */
    protected $dontReport = [
        //
    ];

    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *
     * @var array
     */
    protected $dontFlash = [
        'password',
        'password_confirmation',
    ];

    /**
     * Report or log an exception.
     *
     * @param  \Throwable  $exception
     * @return void
     *
     * @throws \Throwable
     */
    public function report(Throwable $exception)
    {
        parent::report($exception);
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Throwable  $exception
     * @return \Symfony\Component\HttpFoundation\Response
     *
     * @throws \Throwable
     */
    public function render($request, Throwable $exception)
    {
        return parent::render($request, $exception);
    }
}

    上面的处理类主要包含 2 个功能:报告和显示所有的异常信息。

    report 方法用于将错误记录到日志文件中。同时,关注一项重要的 dontReport 属性,它列出了所有不应该被记录到日志的异常类别。

    如果说 report 方法是用于记录或报告错误,那么 render 方法是用于将错误渲染显示在屏幕上。事实上,当异常发生时,这个方法决定了哪些内容将被展示给用户。

    render 方法也允许你针对不同类别的错误自定义响应值。

    至此我们就可以自己定义想要捕获的异常类型了,我们按照异常级别,设置了多种异常类型和日志记录。并且在render方法中进行异常捕获打印。

...

use Illuminate\Support\Facades\Log;

...

protected $code = 0;
protected $levels = [
    100 => 'debug',
    200 => 'info',
    300 => 'notice',
    400 => 'notice',
    500 => 'warning',
    600 => 'error',
    700 => 'critical',
    800 => 'alert',
    900 => 'emergency',
];

...

public function render($request, Throwable $exception)
{
    $classArray = explode(DIRECTORY_SEPARATOR, get_class($exception));
    switch (end($classArray)) {
        case 'MethodNotAllowedHttpException':
            $this->code = 500;
            break;
        case 'NotFoundHttpException':
            $this->code = 600;
            break;
        case 'QueryException':
            $this->code = 700;
            break;
        case 'ReflectionException':
            $this->code = 800;
            break;
        default :
            $this->code = 900;
    }
    if ($this->code) {
        $msg = [
            500 => '请求类型不匹配',
            600 => '请求地址未开放',
            700 => '数据库语句错误',
            800 => '服务端接口异常',
            900 => '程序错误请重试',
        ];
        $result = [
            'request' => $request->input(),
            'data'    => $exception->getMessage(),
            'code'    => $this->code,
            'msg'     => $msg[$this->code],
            'uuid'    => Uuid::uuid6(),
        ];
        Log::log($this->levels[$this->code], 'Render Data', $result);
        return response()->json($result);
    }
    return parent::render($request, $exception);
}

    你们可能发现100~400的状态码在这里并没有用到,因为这个的级别更低,一般作为控制器中接口对应的状态和日志打印,所以在此就不进行捕获了。

上一篇 下一篇

评论

登录后可发表评论