Laravel 5.5 的错误异常处理机制以及应用实例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LJFPHP/article/details/84305596

一、前言

      我们在开发项目中,难免会因为逻辑上的失误而报错,这些报错的展现形式也就是框架封装好的异常处理机制。在项目上线之前,我们还可以根据框架提供的报错信息来锁定错误代码的位置。但是项目上线之后我们是一定要关闭php的错误提示的。这个时候,错误日志以及自定义一些异常处理机制就显得尤为重要。

      关于laravel的错误日志相关,大家可以参考laravel 5.5的文档,讲的很清楚,咱们这里主要是学习一下laravel的异常处理机制以及自定义一些异常处理。
关于laravel的错误日志

关于laravel错误异常处理机制官方文档 这部分更多的是异常处理的底层部分,强烈推荐大家看一看。

二、laravel的异常处理机制

1、php的异常

      先了解php的异常机制,常见的错误报告,try{}catch(){}的大致用法等,这样对于异常就有个大致的了解。其次是异常和错误是不一样的,大家可以参考这篇文章:https://www.cnblogs.com/zyf-zhaoyafei/p/6928149.html ,这样心里对于php的错误,异常就有个数了。

php手册:http://php.net/manual/zh/language.exceptions.php

      我们可以在代码中使用try{}catch(){}来捕获异常,然后进行处理。但程序中可能会出现大量的异常,此时应该使用laravel提供的去全局异常捕获,对于不需要处理的异常添加到 $dontReport = []。其中report方法一般是对应的分开记录日志处理,render方法是对应的异常http响应处理。

2、laravel 5.5 的全局异常处理文件Handler.php

laravel的全局捕获在:app/Exceptions/Handler.php

<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{

    protected $dontReport = [
        // 这里放置你不想被处理的异常类,例如:
     //   HttpException::class,
      //  ModelNotFoundException::class,
    ];
    protected $dontFlash = [
    //这部分咱们用不上,暂时保持不动即可
        'password',
        'password_confirmation',
    ];
    public function report(Exception $exception)
    {
   // report 方法用于记录异常或将其发送到外部服务,如 Bugsnag 或 Sentry。默认情况
   //下,report 方法只是简单地将异常传递给记录异常的基类。你可以根据需要来记录异常。
        parent::report($exception);
    }

    public function render($request, Exception $exception)
    {
    //这部分是我们可以自定义的异常处理部分,默认就是我们常见的报错页面
        return parent::render($request, $exception);
    }
}

这部分大家参考laravel5.5文档:Laravel 的错误和日志记录

3、自定义异常之跳转指定页面

扫描二维码关注公众号,回复: 4979796 查看本文章
  public function render($request, Exception $e)
    {
        //TODO 这里一条自定义http错误自动跳转到首页
        if (getenv('APP_ENV') == 'production' && $e instanceof HttpException) {
            Log::error($e);
            return Redirect::to('admin/dashboard');
        }
        return parent::render($request, $e);
    }

参考博客:https://blog.csdn.net/junming4/article/details/52398513

4、自定义错误页面等

 protected function renderHttpException(HttpException $e)
    {
        if (view()->exists('errors.'.$e->getStatusCode()))
        {
            return response()->view('errors.'.$e->getStatusCode(), [], $e->getStatusCode());
        }
        else
        {
            return (new SymfonyDisplayer(config('app.debug')))->createResponse($e);
        }
    }
  比如你想自定义 404 错误页面的话,只要创建一个 resources/views/errors/404.blade.php 的视图文件  
404内容自定义了

5、我自己用到的部分,当debug关闭的时候,进行一些处理

public function render($request, Exception $e)
    {
        if ($e instanceof ModelNotFoundException) {
            $e = new NotFoundHttpException($e->getMessage(), $e);
        }
        //根据配置文件 显示500错误页
        if(env('APP_DEBUG')){
            return parent::render($request, $e);
        } else {
            $user = $request->user();
            if(is_null($user)){
                $userInfo = "用户未登陆";
            }else{
                if($user->type == 3){
                    $userInfo = "用户ID:".$user->id.",用户Idcard:".$user->idcard;
                }else{
                    $userInfo = "用户ID:".$user->id.",用户Email:".$user->email;
                }
            }
            $userInfo = $userInfo.',IP:'.getClientIP();
            if(is_a($e, 'Symfony\Component\HttpKernel\Exception\HttpException')){
                $errMessage = '页面错误!'.$userInfo.',错误地址:'.$request->fullUrl().",状态码:".$e->getStatusCode().",参数:".json_encode($request->all()).",异常信息:".get_class($e);
            }else{
                $errMessage = '页面错误!'.$userInfo.',错误地址:'.$request->fullUrl().",参数:".json_encode($request->all()).",异常信息:".get_class($e);
            }
           $responseData = [
                'status_code'=>500,
                'message'=>'捕获到错误',
                'data'=>'',
            ];
            return response()->json($responseData);
        }
    }

      代码太多显得有点乱,大致意思就是当debug开着的时候,是在测试环境,我们直接显示默认的异常页面即可,方便调试。当项目上线之后,就要关闭默认的异常页面,防止泄露项目信息。同时自定义报错信息,然后记录下来。

      这里的is_a()方法和instanceof方法是一样的,有兴趣的可以百度下,都是判断:某对象是否属于该类 或 该类是此对象的父类(用于确定一个 PHP 变量是否属于某一类 class 的实例)

6、laravel自带的http错误页面

这里放一张图片,大家自己可以找着看看:
在这里插入图片描述

源码部分:是在错误页面下面的Handler.php中的:renderHttpException 方法,有兴趣的朋友可以研究下。

      以上就是博主关于laravel 5.5错误异常处理的理解,网上还有很多好文章,感谢大家的分享,一起加油。

end

猜你喜欢

转载自blog.csdn.net/LJFPHP/article/details/84305596