如何从laravel8 自定义异常处理类的坑中爬出来;新问题:原理是啥?如何自定义日志格式? 
                            
                                                    
                        
                    
                    
  
                    
                    异常处理类的问题解决了,但又抛出了新的问题:1.我解决问题的原理是啥?2.如何自定义日志格式?
自定义异常处理类经常捕捉不到错误,直接显示Error基类错误,我找到解决办法,但具体原理我不懂,希望有大神指点,我补一下解决方案:
希望高手来讲讲原理!感谢
新问题是:自定义的异常类,经常不能被laravel 异常处理类 handler捕捉到,有时可以有时不可以,有时删除缓存就好了,我建议如我小白看看这是一个坑没发生也看看:
回到家,我以为可能公司电脑不好,我又在自家Windows试了试还是一样,然后在Linux虚拟机上,结果依然。
我在捋一下我想要做的:我希望,服务端的异常,比如代码错误,或者未发现的逻辑错误,响应结果只显示简单的代号,但是记录日志(怎么记录自定义格式又是一个问题~),而用户端由于操作失误导致的异常,显示详细一点,但没有要记录。
上代码:异常处理类:需要看我的注释哟~
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;
class Handler extends ExceptionHandler
{
    protected $dontReport = [
    ];
    protected $dontFlash = [
        'current_password',
        'password',
        'password_confirmation',
    ];
    public function register()
    {
    }
    public function render($request,Throwable $e)
    {
    //为什么这么写? 所有客户端的异常都继承BaseException
    // 为什么不用instanceof 因为我担心 所有异常的基类都是Exception
    //具体我就没测试但是这样好用~
        if(get_parent_class(get_class($e)) == "App\\Exceptions\\BaseException")//, $e->getSt()
        {
            return response()->json(['code' => $e->getCode(), 'msg' => $e->getMessage(),'me'=>get_class($e)]);
        }else{
            //如果是服务器的异常在这里显示
            //如果不是测试环境就显示就不显示详细信息
            //如果是测试环境就显示详细信息
             if (env('APP_DEBUG')) {
                return parent::render($request, $exception);
            }
            return response()->json([
                'status' => 500,
                'message' => '服务器错误',
                'me'=> get_class($e),//这里是测试用滴忽略哈
                'father'=>get_parent_class(get_class($e))
            ],500);
        //    return parent::render($request,$e);
        }
    }
}
问题其实不是出现在这里,问题出现在下面的自定义异常类:看注释~
<?php
namespace App\Exceptions;
use Exception;
class BaseException extends Exception
{
//    protected  $status ;
   public function __construct($code, $msg)
   {
       //属性还是得写滴
       $this->code = $code;
       $this->message = $msg;
       //问题出现在这里,这里不能调用父类方法,不然就会出现问题
       //比如handler捕捉不到,一直报Error 错误而不是我们自定义的错误
    //    parent::__construct($code, $msg);
   }
}
先把如何报错的代码拿出来:还是看注释~
use Illuminate\Support\Facades\Route;
Route::get('/abc', function () {
    //这是一段缺少了分号的代码,会报服务端的错误,被动犯错~
    echo "123"
//下面是主动犯错,也就是客户端的异常~
//    throw new \App\Exceptions\UserException(404, '你没有权限啊',200);
});
少分号postman:

主动抛出UserException:

总结:laravel8 如果想和之前laravel5.6-laravel6一样,重写异常处理类,且和我一样分层,异常类中就得将构造方法重写,且不能调用父类的构造方法。
原文从这里开始 laravel8如何用laravel5.8的方法自定义异常处理类:
最近看了一天文章:
重写laravel8异常类
不知道能不能引用外站的贴子,如果不让我就删除。
我依然在测试,找到了一种解决办法:方法极为不推荐!只是希望大神给出优质答案!看到我个人也在努力~
代码位于app/exception/Handler
public function render($request,Throwable $e)
    {
//       $response = parent::render($request,$e);
        //假设客户端的一种异常是:那么返回异常
        if (get_class($e) == "App\\Exceptions\\BaseException") {
            return response()->json(['code' => $e->getCode(), 'msg' => $e->getMessage(),'a'=>get_class($e)], 200);
        }
        //不是客户端的那就是服务器端的:不把具体问题告知客户
        return response()->json([
            'status' => 500,
            'message' => '服务器错误',
        ],500);
    }
说明:
- 我在register方法中使用renderable的闭包依然会被Handler下render覆盖;按理说这与上面的方法没什么区别,不好用可能是缓存问题。
 - 最后测试还是不好用,但是发现如果每次都把session 缓存删除上面的代码就好用了,所以放进renderable的闭包里不一定不好用。
 - 好吧,不推荐是因为不能用instanceof 所以之后客户端的其他异常类都得继续写 if …
 - 另一个问题是捕获,当抛出异常时,不是每次都能捕获到exception,而是直接报出来Error,不能每次都捕获成功是为什么?
 
跪求大神给出解答!
————————————————————分割线———————————————————
先说测试结果:laravel8的异常处理器Handel里的render会覆盖自定义异常类中的render
以下是详细经过,答题的时候说有详细的环境描述更好,希望我不是啰嗦。
在写api接口时,我想自定义异常类,特别是将服务器自身的问题写入日志,客服端只能看到错误码,而如果是客户操作出现的异常,正常响应给客户。
我百度到了上方连接的文章,正好能解决问题,但结果内发现了laravel5与laravel8的不同:
laravel5:
laravel8:
手册里说道自定义异常类可以直接写render

我也模仿定义了一个异常类:

在路由中抛出:

补充:另一种方式

都能正常响应json数据

但这并不是我想要的,我希望客户端的错误与服务器端的分开;
这里我就猜想在自定义异常类中使用自己的render,服务器报错则使用异常处理器handler里的render。
但结果是:异常处理器Handel里的render会覆盖自定义异常类中的render
有大神可以帮忙解答下么?我是真心努力了,百度了,也尽可能的测试了,我愿意付费,我不是有钱人,但真的想学好这本技术,工作上也正好能用上,就算付费也愿意分享大神的解决方法。价格不离谱就行~非常感谢!
          
                    
                    
            

          
          
                关于 LearnKu
              
                    
                    
                    
 
推荐文章: