laravel 异常深度解析

一、前言

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

二、正题

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  IlluminateHttpRequest  $request
     * @param  Exception  $e
     * @return IlluminateHttpResponse
     */
public function render($request, Exception $e) {
    $message = $e->getMessage();
    $code = $e->getCode();
    $displayable = false; // 异常的具体信息是否可显示给用户
    $module = '';
    $data = [];
 [
            '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的形式返回