系统开发过程中我们会使用异常处理机制来控制业务逻辑的运行。比如我们会在try代码款中执行事务,如果执行过程中没有catch到异常,则会执行提交事务的操作,否则将执行回滚事务的操作。我们知道在代码层面处理异常有两个方式,一个是上面的捕获,另一个是直接throw给方法调用者。当某些异常由于没有被捕获,而直接throw了出来,甚至被throw到controller层仍然没有做捕获处理时,laravel将会如何处理这个异常呢?本文讲解laravel处理controller层抛出的异常的统一处理机制。
laravel建立了一个机制来处理从controller方法中抛出的异常,此机制包含两部分
接下来我们通过讲解Handler类和自定义的Exception的结构来说明一个异常从controller层抛出后的经历。
本文基于laravel 8,低版本可能有些微差别,请参考对应版本的官方文档甄别。
App\Exceptions\Handler类包含一个回调方法register 。
在这个方法中你可以定义reportable 和 renderable 闭包来实现报告和渲染异常的逻辑。他们的区别是:
下面的代码和注释说明了如何指定对应异常类型的报告和渲染逻辑。
laravel中可以在自定义的异常类中实现render和report回调。当此类型的异常触发时,将命中report和render回调,执行相应逻辑。如下代码在BusiException类中定义了这两个回调函数。
某些时候报告异常时,想带有对应的业务数据。比如定义一个异常,InvalidOrderException,打印此异常时可能想记录下出错的订单的id。此时可以重写Exception类的context函数,将orderId追加到异常的上下文信息中,打印异常信息的时候可以带上此业务数据。如下代码:
抛出一个带有上下文数据的异常
打印和渲染带有上下文数据的日志以及http响应
handler的$dontReport成员
这里定义的异常类型将不会被report
有时,你可能需要报告异常,但不终止当前请求的处理。report 辅助函数允许您在不渲染错误页面的情况下快速报告异常。
一些异常描述了来自服务器的 HTTP 错误代码。例如,这可能是“找不到页面”错误(404)、“未经授权的错误”(401)甚至是开发人员生成的 500 错误。为了从应用程序的任何地方生成这样的响应,您可以使用abort帮助程序:
abort(404);
从代码分层的角度来看,不建议在非controller层调用此方法。
自定义 404 HTTP 状态代码的错误页面,请创建一个resources/views/errors/404.blade.php. 此文件将用于处理您的应用程序生成的所有 404 错误。此目录中的视图应命名为与它们对应的 HTTP 状态代码相匹配
当你没有实现任何渲染逻辑的时候,laravel默认会将异常处理为http响应。env配置文件中的APP_DEBUG选项如果打开将会暴露异常细节给浏览器响应,所以开发时,此配置应该是true,而生产环境一定要设置为false。
以上就是有关laravel错误处理的全部机制。最佳实践应该是优先在exception类中定义report、render和context逻辑。通用的逻辑可以在handler中定义。
热门评论