IDEA激活码 (2021-09-25)
全网最全idea主题,phpstorm主题,webstorm主题免费下载

异常处理和错误处理

系统开发过程中我们会使用异常处理机制来控制业务逻辑的运行。比如我们会在try代码款中执行事务,如果执行过程中没有catch到异常,则会执行提交事务的操作,否则将执行回滚事务的操作。我们知道在代码层面处理异常有两个方式,一个是上面的捕获,另一个是直接throw给方法调用者。当某些异常由于没有被捕获,而直接throw了出来,甚至被throw到controller层仍然没有做捕获处理时,laravel将会如何处理这个异常呢?本文讲解laravel处理controller层抛出的异常的统一处理机制。

laravel建立了一个机制来处理从controller方法中抛出的异常,此机制包含两部分

接下来我们通过讲解Handler类和自定义的Exception的结构来说明一个异常从controller层抛出后的经历。

本文基于laravel 8,低版本可能有些微差别,请参考对应版本的官方文档甄别。

Handler register 回调方法

App\Exceptions\Handler类包含一个回调方法register 。

在这个方法中你可以定义reportablerenderable 闭包来实现报告和渲染异常的逻辑。他们的区别是:

下面的代码和注释说明了如何指定对应异常类型的报告和渲染逻辑。

自定义异常类的render回调方法和report回调方法

laravel中可以在自定义的异常类中实现renderreport回调。当此类型的异常触发时,将命中report和render回调,执行相应逻辑。如下代码在BusiException类中定义了这两个回调函数

如果同时在自定义的异常类中定义reportrender方法又在handlerregister回调中定义了此类型异常的renderablereportable闭包,则优先选用异常类中的回调,对应闭包将失效,如果想实现调用exception类的回调后继续执行register中的闭包,则在report方法中返回false即可(如上图中的report方法返回了false)。

异常上下文(context)

某些时候报告异常时,想带有对应的业务数据。比如定义一个异常,InvalidOrderException,打印此异常时可能想记录下出错的订单的id。此时可以重写Exception类的context函数,将orderId追加到异常的上下文信息中,打印异常信息的时候可以带上此业务数据。如下代码:

  抛出一个带有上下文数据的异常

打印和渲染带有上下文数据的日志以及http响应 

Handler render 回调方法

这个方法在laravel的官方文档中没有提及相对register方法中的闭包,此方法是laravel的底层方法, 如果重写此方法,将导致register中的闭包不可用,而直接走此重写的render逻辑。

 handler的$dontReport成员

这里定义的异常类型将不会被report

report 辅助函数 

有时,你可能需要报告异常,但不终止当前请求的处理。report 辅助函数允许您在不渲染错误页面的情况下快速报告异常。

abort辅助函数

一些异常描述了来自服务器的 HTTP 错误代码。例如,这可能是“找不到页面”错误(404)、“未经授权的错误”(401)甚至是开发人员生成的 500 错误。为了从应用程序的任何地方生成这样的响应,您可以使用abort帮助程序:

abort(404);

从代码分层的角度来看,不建议在非controller层调用此方法。 

自定义http错误页面 

自定义 404 HTTP 状态代码的错误页面,请创建一个resources/views/errors/404.blade.php. 此文件将用于处理您的应用程序生成的所有 404 错误。此目录中的视图应命名为与它们对应的 HTTP 状态代码相匹配 

另外

当你没有实现任何渲染逻辑的时候,laravel默认会将异常处理为http响应。env配置文件中的APP_DEBUG选项如果打开将会暴露异常细节给浏览器响应,所以开发时,此配置应该是true,而生产环境一定要设置为false。

最佳实践

以上就是有关laravel错误处理的全部机制。最佳实践应该是优先在exception类中定义report、render和context逻辑。通用的逻辑可以在handler中定义。

热门评论

    暂无