本文介绍: laravel 中间件捕获异常失败的原因和解决办法
前提
我希望通过中间件记录用户的请求数据、我的返回数据,如果出现异常捕获异常。
代码
路由文件:追加中间件api-logging,用于记录日志
Route::prefix('api')->middleware(['api', 'api-logging'])->group(function () {
...路由内容
});
namespace AppHttp;
class Kernel extends HttpKernel
{
...其他内容
protected $routeMiddleware = [
... 其他中间件
'api-logging' => AppHttpMiddlewareApiLoggingMiddleware::class,
];
}
重点:中间件的编写
<?php
namespace AppHttpMiddleware;
use Closure;
use IlluminateHttpRequest;
use AppModelsGameThirdPartyCallback;
class ApiLoggingMiddleware
{
public function handle(Request $request, Closure $next)
{
$requestHeaders = $request->header();
$requestData = $request->all();
$source = $request->header('referer') ?? $request->ip();
try {
// 执行请求并获取响应
$response = $next($request);
$responseStatus = $response->status();
$responseContent = $response->getContent();
} catch (Exception $exception) {
// 记录异常信息
GameThirdPartyCallback::create([
'request_headers' => json_encode($requestHeaders),
'callback_data' => json_encode($requestData),
'response_status' => 500, // 或其他适当的错误状态码
'response_content' => 'An error occurred: ' . $exception->getMessage(),
'sources' => $source
]);
// 重新抛出异常,交由Laravel处理
throw $exception;
}
// 记录正常的响应数据
GameThirdPartyCallback::create([
'request_headers' => json_encode($requestHeaders),
'callback_data' => json_encode($requestData),
'response_status' => $responseStatus,
'response_content' => $responseContent,
'sources' => $source
]);
return $response;
}
}
我希望在,下面这段可以当
n
e
x
t
(
next(
next(request); 出现异常被捕获
try {
// 执行请求并获取响应
$response = $next($request);
} catch (Exception $exception) {
// 重新抛出异常,交由Laravel处理
throw $exception;
}
然而并不行,如果控制器中出现了异常,会被laravel的全局异常处理机制捕获,$response = $next($request);
会返回捕获后的异常处理的类,也就是异常已经被处理掉了
最终处理方案
在全局异常处理的时候,将异常内容插入到request中,然后在中间件去获取这个自定义的属性
- 全局处理文件中,加入下面这段代码
namespace AppExceptions;
use IlluminateFoundationExceptionsHandler as ExceptionHandler;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* Render an exception into an HTTP response.
*
* @param IlluminateHttpRequest $request
* @param Throwable $exception
* @return SymfonyComponentHttpFoundationResponse
*/
public function render($request, Throwable $exception)
{
// 这里这段的内容是为了让异常内容可以被中间件获取
// 因为控制器的异常会被laravel全局异常直接捕获,导致中间件获取的内容是异常页面
$request->attributes->set('exception_message', $exception->getMessage());
return parent::render($request, $exception);
}
}
然后中间件中获取exception_message
<?php
namespace AppHttpMiddleware;
use Closure;
use IlluminateHttpRequest;
use AppModelsGameThirdPartyCallback;
class ApiLoggingMiddleware
{
public function handle(Request $request, Closure $next)
{
$requestHeaders = $request->header();
$requestData = $request->all();
$source = $request->header('referer') ?? $request->ip();
$response = $next($request); // 如果这里产生了异常,不会在这里try catch。而是直接返回了response的错误内容
$responseStatus = $response->status();
if ($responseStatus >= 400 && $responseStatus < 600) {
GameThirdPartyCallback::create([
'request_headers' => json_encode($requestHeaders),
'callback_data' => json_encode($requestData),
'response_status' => $responseStatus,
'response_content' => $request->attributes->get("exception_message"),
'sources' => $source
]);
} else {
...
}
return $response;
}
}
原文地址:https://blog.csdn.net/fendouweiqian/article/details/135556921
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_56904.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。