容器绑定异常处理类
$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;
}