I am developing a Laravel 12 API app with Sanctum authentication (SPA). I am facing a behavior in which Laravel is logging the custom exception twice.
The custom exception declaration is as follows:
use Exception;
use Throwable;
use App\Exceptions\Contracts\ContextDetailsInterface;
use GraphQL\Error\ClientAware;
use GraphQL\Error\ProvidesExtensions;
class CustomException extends Exception implements ClientAware, ProvidesExtensions, ContextDetailsInterface
{
// purposely omitted
}
The custom exception is raised from a service class method that is called by a controller class.
class CustomController extends Controller
{
protected $myService;
...
public function process(CustomFormRequest $request)
{
$payload = $request->payload();
// the method call failed and raised exception
$state = $this->myService->processPayload($payload);
// omitted
return response()->json($response, $code);
}
}
Spent hours of investigation to figure out the reason, but to no avail.
Here's the log output:
2025-09-30 15:20:59.965 [$f12f54acv] local.ERROR Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful(L26) service.err101 {"exception":"[object] (Custom\\Exceptions\\CustomException(code: 400): service.err101 at /dev/repo/backend/src/app/Services/MyService.php:24)"}
2025-09-30 15:20:59.966 [$f12f54acv] local.WARNING App\Exceptions\ExceptionHandler(L344) MyService exception raised {"exception":"CustomException","message":"service.err101","file":"/dev/repo/backend/src/app/Services/MyService.php","line":24,"details":"invalid service key."}
The 1st entry is being generated by Laravel (Middleware?). The 2nd one (which is the expected log entry) is generated by my ExceptionHandler class that is called in bootstrap\app.php (->withExceptions).
I still don't understand why an ERROR level of the same custom exception is being logged in EnsureFrontendRequestsAreStateful.
Any hint as to why?
Thank you in advance.
Update-1: As suggested in the comment, I called dontReportDuplicates() as below in bootstrap\app.php, but the log duplication was not resolved.
->withExceptions(function (Exceptions $exceptions): void {
$exceptions->dontReportDuplicates();
$exceptions->render(function (Throwable $e, Request $request) {
// omitted
});
})->create();