Laravel 默认情况下不记录 404 错误。我想改变这种行为。
大多数指南都说要在以下块中手动记录:
public function register(): void
{
$this->reportable(function (Throwable $e) {
// Handle 404 here
});
}
但似乎 404 异常由于某种原因甚至没有触发此方法。
执行以下操作在技术上是可行的,但放在我需要的任何地方很乏味:
try {
$model = User::findOrFail(99999);
} catch (ModelNotFoundException $e) {
Log::error($e);
throw $e;
}
我正在使用 Laravel 10。
我做错了什么?
你可以尝试使用
stopIgnoring
方法。
https://laravel.com/docs/10.x/errors#ignoring-exceptions-by-type
use Symfony\Component\HttpKernel\Exception\HttpException;
/**
* Register the exception handling callbacks for the application.
*/
public function register(): void
{
$this->stopIgnoring(HttpException::class);
// ...
}
这样,您将忽略所有 HTTP 异常。或者,尝试使用
Symfony\Component\HttpKernel\Exception\NotFoundHttpException
看看它是否只会忽略 HTTP 404。
这就是为什么第一种方法没有按预期工作,以及在 Laravel 10 中处理 404 日志记录的更好方法。
了解问题
App\Exceptions\Handler 类中的可报告方法主要设计用于报告错误跟踪服务的异常,而不是专门用于记录每个 404。这就是为什么您没有看到预期的效果。
推荐方法
以下是如何在 Laravel 10 中有效记录 404 错误:
创建中间件(例如 LogNotFoundRequests.php)
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Illuminate\Support\Facades\Log;
class LogNotFoundRequests
{
public function handle(Request $request, Closure $next)
{
$response = $next($request);
if ($response->status() === 404) {
Log::error('404 Not Found: ' . $request->path());
}
return $response;
}
}
在 app\Http\Kernel.php 文件中注册中间件。将其添加到您的全局中间件堆栈或特定路由组。
创建事件监听器(例如 LogNotFoundException.php)
<?php
namespace App\Listeners;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class LogNotFoundException
{
public function handle(NotFoundHttpException $event)
{
Log::error('404 Not Found: ' . $event->getRequest()->path());
}
}
在 App\Providers\EventServiceProvider.php 文件中注册监听器:
protected $listen = [
// ... other events
NotFoundHttpException::class => [
LogNotFoundException::class,
],
];
选择方法
中间件:适合简单、直接记录请求路径。 事件监听器:如果您想要更精细的错误处理,例如将数据传递到其他系统或创建自定义日志消息,则可以提供更大的灵活性。
为什么要避免 try-catch 块
在任何地方手动添加带有 ModelNotFoundException 的 try-catch 块不太理想,因为:
重复:它会产生不必要的代码重复。 有限的控制:它不允许您轻松自定义日志消息或日志级别。