美文网首页
laravel 中自定义异常

laravel 中自定义异常

作者: JJNile | 来源:发表于2019-03-15 21:56 被阅读0次

    前言

    项目上线时,我们不能将系统的报错信息反馈给用户,因为这样特别不安全和友好,所以我们要设置.env中APP_DEBUG = false。

    尽管这样不会在显示代码错误的信息,但是laravel会将显示空白的 Whoops, looks like something went wrong,这无法给访问者提供任何有价值的信息也不美观。

    所以我们需要需要捕捉错误,处理它们,然后用实际可以理解的错误信息返回给用户。

    源码解析

    首先看下laravel中的异常处理类:

    app/Exceptions/Handler.php

     <?php
    
    namespace App\Exceptions;
    
    use Exception;
    use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
    
    class Handler extends ExceptionHandler
    {
        // 不被处理的异常错误
        protected $dontReport = [
            InvalidRequestException::class,
        ];
    
        // 认证异常时不被flashed的数据
        protected $dontFlash = [
            'password',
            'password_confirmation',
        ];
    
        // 上报异常至错误driver,如日志文件(storage/logs/laravel.log),第三方日志存储分析平台
        public function report(Exception $exception)
        {
            parent::report($exception);
        }
    
        // 将异常信息响应给客户端
        public function render($request, Exception $exception)
        {
            return parent::render($request, $exception);
        }
    }
    
    

    当 Laravel 处理一次请求时,在启动文件中注册了以下服务:

    bootstrap/app.php

    .
    .
    // 绑定 http 服务提供者
    $app->singleton(
        Illuminate\Contracts\Http\Kernel::class,
        App\Http\Kernel::class
    );
    // 绑定 cli 服务提供者
    $app->singleton(
        Illuminate\Contracts\Console\Kernel::class,
        App\Console\Kernel::class
    );
    // 这里将异常处理器的服务提供者绑定到了 `App\Exceptions\Handler::class`
    $app->singleton(
        Illuminate\Contracts\Debug\ExceptionHandler::class,
        App\Exceptions\Handler::class
    );
    .
    .
    

    我们大概了解了异常,其中最主要的两个方法是:

    report() 如果你想要做一些额外的日志记录,则使用report(), 比如将错误发送到电子邮件,Slack等。
    
    render() 如果你想直接从Exception类重定向错误或返回HTTP响应(如自己的 Blade 文件),则使用render()
    

    那么现在在自定义常用的两个异常类:用户错误行为触发的异常和系统内部异常

    自定义异常

    自定义常用的两个异常:

    1. 用户错误行为触发的异常
    2. 系统内部异常

    用户错误行为触发的异常

    $ php artisan make:exception InvalidRequestException
    

    app/Exceptions/InvalidRequestException.php

    <?php
    namespace App\Exceptions;
    
    use Exception;
    use Illuminate\Http\Request;
    use Throwable;
    
    class InvalidRequestException extends Exception {
        public function __construct(string $message = "", int $code = 0, Throwable $previous = null) {
            parent::__construct($message, $code, $previous);
        }
    
        public function render(Request $request) {
    
            // 如果是 AJAX 请求则返回 JSON 格式的数据
            if ($request->expectsJson()) {
                return response()->json(['msg' => $this->message], $this->code);
            }
    
            return view('error', ['msg' => $this->message]);
        }
    }
    
    
    

    系统内部异常

    $ php artisan make:exception InternalException
    

    app/Exceptions/InternalException.php

    <?php
    
    namespace App\Exceptions;
    
    use Exception;
    use Illuminate\Http\Request;
    use Throwable;
    
    class InternalException extends Exception {
        protected $msgForUser;
    
        public function __construct(string $message = "", string $msgForUser = "系统内部错误", int $code = 0, Throwable $previous = null) {
            parent::__construct($message, $code, $previous);
            $this->msgForUser = $msgForUser;
        }
    
        public function render(Request $request) {
    
            if ($request->expectsJson()) {
                return response()->json(['msg' => $this->msgForUser], $this->code);
            }
    
            return view('error', ['msg' => $this->msgForUser]);
        }
    
    
    }
    

    应用到代码中

    抛出异常

    use App\Exceptions\InvalidRequestException;
    .
    .
    .
    if (!$activate) {
        throw new InvalidRequestException('不再进行中');
    }
    

    参考

    https://segmentfault.com/a/1190000018381889
    https://juejin.im/entry/5af517c26fb9a07acd4dc5b8
    https://swoole.app/2018/04/11/laravel%E4%BD%BF%E7%94%A8%E8%87%AA%E5%AE%9A%E4%B9%89%E5%BC%82%E5%B8%B8%E7%B1%BB/

    相关文章

      网友评论

          本文标题:laravel 中自定义异常

          本文链接:https://www.haomeiwen.com/subject/dvddmqtx.html