异常处理是编程中十分重要但也最容易被人忽视的语言特性,它为开发者提供了处理程序运行时错误的机制,对于程序设计来说正确的异常处理能够防止泄露程序自身细节给用户,给开发者提供完整的错误回溯堆栈,同时也能提高程序的健壮性。
这篇文章我们来简单梳理一下Laravel中提供的异常处理能力,然后讲一些在开发中使用异常处理的实践,如何使用自定义异常、如何扩展Laravel的异常处理能力。
注册异常Handler
这里又要回到我们说过很多次的Kernel处理请求前的bootstrap阶段,在bootstrap阶段的IlluminateFoundationBootstrapHandleExceptions
部分中Laravel设置了系统异常处理行为并注册了全局的异常处理器:
class HandleExceptions
{
public function bootstrap(Application $app)
{
$this->app = $app;
error_reporting(-1);
set_error_handler([$this, 'handleError']);
set_exception_handler([$this, 'handleException']);
register_shutdown_function([$this, 'handleShutdown']);
if (! $app->environment('testing')) {
ini_set('display_errors', 'Off');
}
}
public function handleError($level, $message, $file = '', $line = 0, $context = [])
{
if (error_reporting() & $level) {
throw new ErrorException($message, 0, $level, $file, $line);
}
}
}
set_exception_handler([$this, 'handleException'])
将HandleExceptions
的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 getExceptionHandler()
{
return $this->app->make(ExceptionHandler::class);
}
// 渲染CLI请求的异常响应
protected function renderForConsole(Exception $e)
{
$this->getExceptionHandler()->renderForConsole(new ConsoleOutput, $e);
}
// 渲染HTTP请求的异常响应
protected function renderHttpResponse(Exception $e)
{
$this->getExceptionHandler()->render($this->app['request'], $e)->send();
}