一、前言

  做一件事,不仅要知其然,更要知其所以然。大部分的人都生活在别人设计的世界里,不是没有能力去更深一层,更进一步,而是因为自己懒得去思考。也许自己现在要做的就是:不要让自己舒服吧。

二、正题

1. 定义异常

class StorageException extends MaterialException
{
/**
* @var integer ERROR_CODE 错误代码基数
*/
const ERROR_CODE = 12; // 这个有用,后面会讲到 /**
* @var string MODULE 模块名称
*/
const MODULE = 'storage';// 这个有用,后面会讲到
/** * @var boolean $displayable 是否展示错误信息给前端标记 */ protected $displayable = false; /** * 不上报到sentry的错误码 * * @var array */ protected $dontReport = [12, 15]; /** * 用户自定义异常代码 */ const RECORD_NOT_EXISTS = [10, '资料记录不存在']; const DB_ERROR = [11, '更新数据库出现异常']; const DIR_EXISTS = [12, '目录已存在'];
}

2. 抛出异常

if (empty($announcement)) {
list($code, $message) = AnnouncementException::ANNOUNCEMENT_DOES_NOT_EXISTS;
throw new AnnouncementException($code, $message);
}

3. laravel 捕获异常,怎么捕获的暂时不得而知,等我修炼修炼再来补充。

4. 异常进入到 Handler.php 中去class Handler extends BaseHandler

{
/**
* A list of the exception types that should not be reported.
*
* @var array
*/
protected $dontReport = [ ]; // 不报告的异常 /**
* Report or log an exception.
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Exception $e
* @return void
*/
public function report(Exception $e)
{
parent::report($e); // 将异常上报,具体的操作看下面
} /**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
    $message = $e->getMessage();
    $code = $e->getCode();
    $displayable = false; // 异常的具体信息是否可显示给用户
    $module = '';
    $data = [];
$result = [
'code' => $code,
'message' => $message,
'displayable' => $displayable,
'module' => $module,
'data' => $data
];
\Log::error("exception response", $result); // 记录错误到日志中
$response = new Response($result, 200); return $response;
}
}

5. report函数

class BaseHandler extends ExceptionHandler
{
/**
* Report or log an exception.
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Exception $exception
* @return void
*/
public function report(Exception $exception)
{
      
if (app()->environment('production') && $this->shouldReport($exception)) { // app()->environment('production')这个是什么不知道 // shouldReport判断是不是应该报告
if ($exception instanceof SentryException) { // sentry错误就对senrty错误进行处理
$this->dispatchException($exception);
} else {
app('sentry')->captureException($exception); // 非sentry错误将会捕捉
}
} parent::report($exception);
// @codeCoverageIgnoreStart
}
// @codeCoverageIgnoreEnd /**
* Method dispatchException
* 构造 sentry 日志信息
*
* @param Reportable $exception
*/
private function dispatchException(Reportable $exception)
{
$httpInstance = HttpInputInfo::getInstance();
$traceId = $httpInstance->getTraceId();
$reportable = $exception->getReportable(); if (!$reportable) {
return false;
} app('sentry')->captureException($exception, [
'level' => $exception->getLevelName($exception->getLevel()),
'tags' => [
'module' => $exception->getModule(), // 上面的module
'code' => $exception->getCode(), // 上面的code
'trace_id' => $traceId,
],
'extra' => $exception->getExtra(),
]);
}
}

6. render函数

  render函数主要是把错误以httpResponse的形式返回

laravel 异常深度解析的更多相关文章

  1. (转载)(收藏)OceanBase深度解析

    一.OceanBase不需要高可靠服务器和高端存储 OceanBase是关系型数据库,包含内核+OceanBase云平台(OCP).与传统关系型数据库相比,最大的不同点, 是OceanBase是分布式 ...

  2. 深度解析Java8 – AbstractQueuedSynchronizer的实现分析(上)

    本文首发在infoQ :www.infoq.com/cn/articles/jdk1.8-abstractqueuedsynchronizer 前言: Java中的FutureTask作为可异步执行任 ...

  3. mybatis 3.x源码深度解析与最佳实践(最完整原创)

    mybatis 3.x源码深度解析与最佳实践 1 环境准备 1.1 mybatis介绍以及框架源码的学习目标 1.2 本系列源码解析的方式 1.3 环境搭建 1.4 从Hello World开始 2 ...

  4. 并发编程(十五)——定时器 ScheduledThreadPoolExecutor 实现原理与源码深度解析

    在上一篇线程池的文章<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中从ThreadPoolExecutor源码分析了其运行机制.限于篇幅,留下了Scheduled ...

  5. 并发编程(十二)—— Java 线程池 实现原理与源码深度解析 之 submit 方法 (二)

    在上一篇<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中提到了线程池ThreadPoolExecutor的原理以及它的execute方法.这篇文章是接着上一篇文章 ...

  6. 蓝鲸DevOps深度解析系列(2):蓝盾流水线初体验

    关注嘉为科技,获取运维新知 前面一篇文章<蓝鲸DevOps深度解析系列(1):蓝盾平台总览>,我们总览了蓝鲸DevOps平台的背景.应用场景.特点和能力: ​ 接下来我们继续解析蓝盾平台的 ...

  7. laravel源码解析

    本专栏系列文章已经收录到 GitBooklaravel源码解析 Laravel Passport——OAuth2 API 认证系统源码解析(下)laravel源码解析 Laravel Passport ...

  8. Java 8 Optional 类深度解析

    Java 8 Optional 类深度解析 身为一名Java程序员,大家可能都有这样的经历:调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法.我们首先要判断这个返回值是否为null,只 ...

  9. 《SEO深度解析——全面挖掘搜索引擎优化的核心秘密》

    <SEO深度解析——全面挖掘搜索引擎优化的核心秘密> 基本信息 作者: 痞子瑞 出版社:电子工业出版社 ISBN:9787121224041 上架时间:2014-2-28 出版日期:201 ...

随机推荐

  1. Zookeeper学习记录(二):使用以及配置

    zookeeper已经介绍了它的原理设计以及实现方式,我们接下来介绍zookeeper的使用方法以及简单配置. 下载 获取Zookeeper的发布包,从Apache下载映像中下载一个最新稳定版本. 单 ...

  2. Code Blocks+gtest环境配置

    本文仅介绍Code::Blocks+gtest环境配置,gtest具体使用方法请参考: 玩转Google开源C++单元测试框架Google Test系列(gtest)(总) http://www.cn ...

  3. GDPR给安全的影响

    违反GDPR的代价过于巨大,因而你不得不为那些预料不到的后果考虑,而且因为无法使用Whois数据,无形中也扩大了威胁界面.因为GDPR的存在,可供黑客入侵的威胁界面显著增长,不是增加了一点点,而是翻了 ...

  4. 笔试题二(java面向对象、多线程、集合)

    1.final关键字的特点 final修饰变量时,在堆内存中的地址是不变的,但对象的内容是可变的.//思考,找例子 2.静态变量的特点 实例变量是用对象引用,要先实例化对象,而静态变量属于类,只要类加 ...

  5. html判断当前页面是否在iframe中/顶级document中

    在使用div+iframe布局的应用中,通常我们希望在session超时或者未登录访问时跳转到登录页面,默认情况下iframe中的页面无法直接覆盖父页面,因此需要在登录页面加载的时候判断一下当前是否为 ...

  6. Android实践项目汇报-改(一)

    Google天气客户端NABC Need(需求):  功能性需求分析 天气预报客户端,顾名思义就是为用户提供实时准确的天气信息,方便用户出行生活.根据用户日常需求,软件完成后点开,载入界面,显示查询界 ...

  7. C++ 文件大小格式化

    #include <iostream> #include <windows.h> using namespace std; /*文件大小格式化 *param [in] dwSi ...

  8. DD-WRT自定义脚本更新花生壳DDNS

    N年以前买了一个tp-link 841n v7,一直用的还算可以吧,除了不定期重启路由器,不然网速慢的龟爬啊!这也是TP原厂固件的通病,于是刷了DD-WRT,话说DD确实很爽,除了功能强大之外,而且很 ...

  9. CSAPP学习笔记 第一章 计算机系统漫游

    Ch 1.0 1.计算机系统是由硬件和系统软件组成的 2.本书阐述了计算机组件是如何工作的以及执行组件是如何影响程序正确性和性能的. 3.通过跟踪hello程序的生命周期来开始对系统的学习. #inc ...

  10. 基于MySQl的分页显示

    <%@page import="java.sql.DriverManager"%> <%@page import="java.sql.ResultSet ...