如何从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
有大神可以帮忙解答下么?我是真心努力了,百度了,也尽可能的测试了,我愿意付费,我不是有钱人,但真的想学好这本技术,工作上也正好能用上,就算付费也愿意分享大神的解决方法。价格不离谱就行~非常感谢!
推荐文章: