异常处理

异常处理

所有异常都是由 App\Exceptions\Handler 类处理。此类包含一个 register 方法,可以在其中注册自定义异常报告程序。

自定义异常

<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Support\Facades\Log;

class InvalidOrderException extends Exception
{
    /**
     * 自定义报告异常
     *
     * @return bool|null
     */
    public function report()
    {
        $data = [
            'message' => $this->message,
            'code' => $this->code,
            'line' => $this->line,
            'file' => $this->file
        ];

        //do something
        Log::error('无效订单'.implode(PHP_EOL, $data));
        // 返回false,Laravel 依然会使用默认的日志配置记录下应用异常。返回null,则不会处理。
    }

    /**
     * 自定义渲染异常 HTTP 响应。
     *
     * @param  \Illuminate\Http\Request $request
     * @return \Illuminate\Http\Response
     */
    public function render($request)
    {
        //你自己处理响应,或者,系统默认处理响应或渲染异常页面
        return response()->json(['code' => 0000, 'message' => '无效订单'], 200);

        //自定义异常渲染页
        //return response()->view('static_pages/home', [], 500);
        //不返回响应对象,则使用默认的异常渲染
    }
}

任意位置抛异常

use App\Exceptions\InvalidOrderException;
throw new InvalidOrderException($message = "", $code = 0);

重写默认异常处理

<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use  Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use App\Exceptions\InvalidOrderException;

class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that are not reported.
     * 不应上报的异常类型列表。
     * @var array
     */
    protected $dontReport = [
        //
    ];

    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *
     * @var array
     */
    protected $dontFlash = [
        'password',
        'password_confirmation',
    ];

    /**
     * Register the exception handling callbacks for the application.
     *
     * @return void
     */
    public function register()
    {
        //通过闭包方式报告异常
        $this->reportable(function  (InvalidOrderException $e)  {  
                //do something
        });
        //渲染异常处理,自定义异常渲染页
        $this->renderable(function  (InvalidOrderException $e,  $request)  {  
            return  response()->view('errors.invalid-order',  [],  500);  
        });
        //返回异常处理
        $this->renderable(function  (NotFoundHttpException $e,  $request)  {  
            if  ($request->is('api/*'))  {  
                return  response()->json([  'message'  =>  'Record not found.'  ],  404);
            } 
        });
    }

    /**
    * 获取默认日志的上下文变量
    *
    * @return array
    */
    protected function context()
    {
        //任何你能获取到,或想记录的信息
        $request = request();
        return array_merge(parent::context(), [
            'token' => $request->token,
        ]);
    }
}

全局日志上下文

在可用的情况下, Laravel 会自动将当前用户的编号作为数据添加到每一条异常日志信息中。 父类默认处理。

    /**
     * Get the default context variables for logging.
     *
     * @return array
     */
    protected function context()
    {
        try {
            return array_filter([
                'userId' => Auth::id(),
                // 'email' => optional(Auth::user())->email,
            ]);
        } catch (Throwable $e) {
            return [];
        }
    }

您可以通过重写 App\Exceptions\Handler 类中的 context 方法来定义您自己的全局上下文数据(环境变量)。此后,每一条异常日志信息都将包含这个信息:

    /**
    * 获取默认日志的上下文变量
    *
    * @return array
    */
    protected function context()
    {
        //任何你能获取到,或想记录的信息
        $request = request();
        return array_merge(parent::context(), [
            'token' => $request->token,
        ]);
    }

自定义异常日志上下文

着实看不懂,难道是想让开发者通过 $e->context(),获取自定义异常信息?看了会源码,也没发现哪里有调用。尴尬 ̄□ ̄||

    /**
     * Get the exception's context information.
     *
     * @return array
     */
    public function context()
    {
        return ['order_id' => $this->orderId];
    }
本作品采用《CC 协议》,转载必须注明作者和本文链接
写的不好,就当是整理下思绪吧。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!