Laravel Exception处理逻辑解析

vendor/laravel/framework/src/Illuminate/Foundation/Application.php

  1. app首先继承了container,作为一个容器类存在
  2. 注册了laravel运行过程的需要的基础类进容器,并且生成了运行需要的实例。承担了初始化功能。这里需要额外说一下,app里面说的所谓注册,不是指绑定,应该是直接直接实例化了,并注入到容器。但是,针对provider,实例化了provider,并运行了,并不会生成实际的类,而是将类绑定。

ExceptionHandler的注册就是在Application的__construct方法中。

$this->registerErrorHandling();

接着我们来到定义该方法的trait:RegistersExceptionHandlers找到该方法。看一下该方法实现了什么样的逻辑。便于理解我加上了一些注释。

protected function registerErrorHandling()
{
error_reporting(-1);//-1报告所有异常,包括后续新定义的异常级别,作用与E_ALL相同 /** set_error_handler,set_exception_handler,register_shutdown_function分别注册不同级别不同类型异常的处理方法。 */ set_error_handler(function ($level, $message, $file = '', $line = 0) {
if (error_reporting() & $level) {
throw new ErrorException($message, 0, $level, $file, $line);
}
});//代替标准错误处理方法 set_exception_handler(function ($e) {
$this->handleUncaughtException($e);
});//兜底异常处理方法注册 register_shutdown_function(function () {
$this->handleShutdown();
});//注册一个在脚本正常或非正常情况终止执行时调用的方法。(终极兜底)
}

我们看到laravel主要通过三个原生方法来实现主要的ExceptionHandler机制。下面我们分开看一下这里都分别注册了哪些函数。

set_error_handler

function ($level, $message, $file = '', $line = 0) {
if (error_reporting() & $level) {
throw new ErrorException($message, 0, $level, $file, $line);
}
}

这块很简单,set_error_handler注册的函数会代替原生的报错处理逻辑。这里可以看到laravel将执行error作为异常抛出。并且保留了error的主要信息。(level,msg,file,line)

set_exception_handler

/**set_exception_handler(function ($e) {
$this->handleUncaughtException($e);
});**/ protected function handleUncaughtException($e)
{
//从容器中实例化一个真正的handler。(使用make方法)
$handler = $this->resolveExceptionHandler();
//如果获取到的是Error,通过Error信息实例化一个已定义的“可抛出的致命错误”
if ($e instanceof Error) {
$e = new FatalThrowableError($e);
}
//记录日志(先判断是否报告)
$handler->report($e);
//render错误
if ($this->runningInConsole()) {
$handler->renderForConsole(new ConsoleOutput, $e);
} else {
$handler->render($this->make('request'), $e)->send();
}
}
  1. resolveExceptionHandler方法从容器中make了一个handler实例,从该方法可以找到laravel实现的handler方法。该方法会判断是否绑定抽象类型来判断使用开发者自行绑定的ExceptionHandler还是系统自带的。handler的作用只有一点,就是解析异常,并将异常处理成我们想要的,更加用户友好的方式展示。(++render方法,可以看“Laravel\Lumen\Exceptions\Handler”,该类实现了Laravel的ExceptionHandler接口,想要自定义异常输出的话也可以参考该类++)
  2. report和render方法都是handler中定义的,report会先进行判断,并根据判断结果决定是否记录log。render自然不必多说,formatexception info,并作为一个HTTP response输出。

register_shutdown_function

protected function handleShutdown()
{
if (! is_null($error = error_get_last()) && $this->isFatalError($error['type'])) {
$this->handleUncaughtException(new FatalErrorException(
$error['message'], $error['type'], 0, $error['file'], $error['line']
));
}
}

error_get_last()是5.2版本实现的方法,能够很好的配合的register_shutdown_function进行兜底处理。改善了需要自定义变量判断的方法。

error_get_last 返回了一个关联数组,描述了最后错误的信息,以该错误的 "type"、 "message"、"file" 和 "line" 为数组的键。

另外,该方法规定只有致命的错误才会启动。

Laravel Exception处理逻辑解析的更多相关文章

  1. Laravel Exception结合自定义Log服务的使用

    Laravel Exception结合自定义Log服务的使用 第一部分:laravel关于错误和异常的部分源码 第二部分:自定义异常的使用(结合serviceprovider monolog elas ...

  2. ZooKeeper(二):多个端口监听的建立逻辑解析

    ZooKeeper 作为优秀的分布系统协调组件,值得一探究竟.它的启动类主要为: 1. 单机版的zk 使用 ZooKeeperServerMain 2. 集群版的zk 使用 QuorumPeerMai ...

  3. Hystrix失败处理逻辑解析

    在上篇文章Hystrix工作流程解析中,我们整体介绍了Hystrix的工作流程,知道了Hystrix会在下面四种情况下发生降级: 熔断器打开 线程池/信号量跑满 调用超时 调用失败 本篇文章则介绍一下 ...

  4. laravel启动过程简单解析

    :first-child{margin-top:0!important}img.plugin{box-shadow:0 1px 3px rgba(0,0,0,.1);border-radius:3px ...

  5. Spring 声明事务中transactionAttributes属性 + - Exception 实现逻辑

    下面是一段典型的Spring 声明事务的配置: <bean id=“baseTxProxy” lazy-init=“true”class=“org.springframework.transac ...

  6. laravel的启动过程解析

    laravel的启动过程,也是laravel的核心,对这个过程有一个了解,有助于得心应手的使用框架,希望能对大家有点帮助. 统一入口 laravel框架使用了统一入口,入口文件:/public/ind ...

  7. ZooKeeper(五):事务处理之更新数据逻辑解析

    通过前些文章,我们已经完全从整体架构和数据接入方面理解了ZK的前情工作.接下来,我们就来看ZK的正式工作吧. 本文以 setData /a data 这个命令作为出发点,来观察zk是如何处理来自客户端 ...

  8. 随便聊聊 SOA & SOAP & WebService 的一些东西,以及客户端开发的代码逻辑解析

    http://blog.csdn.net/hikaliv/article/details/6459779 一天的时间调通了一个 WebService 的 Java 端的 C/S.一个 Android  ...

  9. LARAVEL IOC容器 示例解析

    <?php class People { public $dog = null; public function __construct() { $this->dog = new Dog( ...

随机推荐

  1. Python3.6安装及引入Requests库

    本博客可能没有那么规范,环境之类的配置.只是让你直接开始编程写python. 至于各种配置网络上有多种方法. 本文仅代表我的观点的一种方法. 电脑环境:win10 64位 第一步:下载python. ...

  2. 【BZOJ2820】YY的GCD

    [BZOJ2820]YY的GCD Description 神犇YY虐完数论后给傻×kAc出了一题 给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的( ...

  3. 华为交换机常用命令(以s5700-SI为例)

    交换机的三种模式: Access模式: 一般用来连接计算机与交换机. 此模式下有一个PVID就是本端口所属的VLAN号,如果从链路上收到无标签的帧,则打上默认VLAN号,然后发给其他端口,如果从链路上 ...

  4. mysql数据库的test类型

    文章参考自 window系统参考:http://blog.sina.com.cn/s/blog_46f7bb6d0102vde3.html linux 参考:http://www.linuxeye.c ...

  5. intellij idea 修改背景保护色&&修改字体&&快捷键大全(转)

    文章转自http://blog.csdn.net/hpf911/article/details/16888797 近Idea比较流行,Eclipse因为maven的问题,运行起来非常慢,各种提示也不够 ...

  6. 梯度下降(Gradient Descent)

    在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent)是最常采用的方法之一,另一种常用的方法是最小二乘法.这里就对梯度下降法做一个完整的总结. 1. 梯度 在微 ...

  7. SkylineGlobe 邻近度(Proximity)分析JavaScript源代码

    邻近度(Proximity)描述了地理空间中两个地物距离相近的程度,是空间分析的一个重要手段. <html xmlns="http://www.w3.org/1999/xhtml&qu ...

  8. win10 + VS2010 + OpenCV2.4.10重编译OpenCV开发环境搭建

    win10 + VS2010 + OpenCV2.4.10重编译OpenCV开发环境搭建 重编译的优点:能够调试的时候看OpenCV的源码. 重编译要得到的东西:Debug版本号和Release版本号 ...

  9. Luogu4640 BJWC2008 王之财宝 容斥、Lucas

    传送门 题意:有$N$种物品,其中$T$个物品有限定数量$B_i$,其他则没有限定.问从中取出不超过$M$个物品的方案数,对质数$P$取模.$N,M \leq 10^9 , T \leq 15 , P ...

  10. CF535E Tavas and Pashmaks 单调栈、凸包

    传送门 题意:有一场比赛,$N$个人参加.每个人有两种参数$a,b$,如果存在正实数$A,B$使得$\frac{A}{a_i} + \frac{B}{b_i}$在$i=x$处取得最大值(可以有多个最大 ...