Laravel异常机制

容器绑定异常处理类

$app = require_once __DIR__.'/../bootstrap/app.php';

app.php中,

$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
);

启动过程中, 在Illuminate\Foundation\Http\Kernel类中, 会调用下面

protected $bootstrappers = [
        'Illuminate\Foundation\Bootstrap\DetectEnvironment',
        'Illuminate\Foundation\Bootstrap\LoadConfiguration',
        'Illuminate\Foundation\Bootstrap\ConfigureLogging',
        'Illuminate\Foundation\Bootstrap\HandleExceptions',
        'Illuminate\Foundation\Bootstrap\RegisterFacades',
        'Illuminate\Foundation\Bootstrap\RegisterProviders',
        'Illuminate\Foundation\Bootstrap\BootProviders',
    ];

每个类中的bootstrap方法, 'Illuminate\Foundation\Bootstrap\HandleExceptions'如下:

 public function bootstrap(Application $app)
    {
        $this->app = $app;

        error_reporting(-1);

        set_error_handler([$this, 'handleError']);

        //调用$this->handleException($e), 处理全局未处理的异常,
        // 将抛出的异常作为参数, 都传给改方法参数, 交由改方法处理

        set_exception_handler([$this, 'handleException']);

        register_shutdown_function([$this, 'handleShutdown']);

        if (! $app->environment('testing')) {
            ini_set('display_errors', 'Off');
        }
    }

handleException如下:

public function handleException($e)
    {
        if (! $e instanceof Exception) {
            $e = new FatalThrowableError($e);
        }

        // 记录日志
        $this->getExceptionHandler()->report($e);

        if ($this->app->runningInConsole()) {
            $this->renderForConsole($e);
        } else {
            // 生成响应
            $this->renderHttpResponse($e);
        }
    }

protected function renderHttpResponse(Exception $e)
    {
        $this->getExceptionHandler()->render($this->app['request'], $e)->send();
    }

protected function getExceptionHandler()
    {
        // 返回最开始绑定的异常处理类App\Exceptions\Handler::class
        return $this->app->make('Illuminate\Contracts\Debug\ExceptionHandler');
    }

调用App\Exceptions\Handler::class的render()方法, 如下

/**
     * Render an exception into an HTTP response.
     * 此方法写自己的异常处理类
     * 覆盖父类render方法
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $e
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $e)
    {
        // 记录日志
        Log::error($e);
        if(app('request')->ajax() || app('request')->wantsJson()) {
            return $this->jsonErrWithException($e);
        } else {
            $data = ['code'=>config('errcode.sys_err'), 'msg'=>trans('error_info.sys_err')];
            if ($e instanceof AuthorizationException) {
                // 暂时这样, 因为有异常没有初始化代码和mess
                $data['code'] = $e->getCode();
                $data['msg'] = $e->getMessage();
  
            } elseif($e instanceof MyException) {
                  // 我们自己定义的异常

            }
            // 自己定义的错误页面
            return response()->view('errors.503', $data, 503);
        }
    }

启动最后一步 , 会调用kernel类的handle()方法, 如下

Illuminate\Foundation\Http\Kernel;
public function handle($request)
    {
        try {
            $request->enableHttpMethodParameterOverride();

            $response = $this->sendRequestThroughRouter($request);
        } catch (Exception $e) {
            // 日志记录异常
            $this->reportException($e);
            // 使用App\Exceptions\Handler::class处理异常
            $response = $this->renderException($request, $e);
        } catch (Throwable $e) {
            $this->reportException($e = new FatalThrowableError($e));

            $response = $this->renderException($request, $e);
        }

        $this->app['events']->fire('kernel.handled', [$request, $response]);

        return $response;
    }

你可能感兴趣的:(Laravel异常机制)