You’re very close—the confusion is understandable! Here’s the problem and how to fix it:
Why Is Your Exception Still Logged?
Returning false from a custom exception’s report() method prevents Laravel from sending your exception to the handler's report() method—this skips logging via Laravel's error channels (database, Bugsnag, etc.).
However, uncaught exceptions (even if rendered nicely for the user) can still bubble up and be caught by PHP’s error handler, which may log them by default if not handled as Laravel expects.
Solution
You should let your exception extend Laravel's base Exception instead of RuntimeException. Laravel looks for the report() method on exceptions that extend its own Exception class. If you extend RuntimeException, your report() method isn't invoked automatically.
So, update your exception like this:
<?php
declare(strict_types=1);
namespace App\Exceptions;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Laravel\Socialite\Two\User as SocialiteUser;
use Exception; // Use this instead of RuntimeException
use Throwable;
class UnregisteredGoogleUser extends Exception
{
public function __construct(
public SocialiteUser $googleUser,
string $message = '',
int $code = 0,
?Throwable $previous = null,
) {
parent::__construct($message, $code, $previous);
}
// This tells Laravel not to report/log this exception
public function report(): bool
{
return false;
}
public function render(Request $request): View
{
return view('exceptions.unregistered-sso-user', []);
}
}
Key Points
- Must extend
Exception, notRuntimeExceptionfor Laravel to respectreport(). - Your
report()is implemented correctly (falsedisables logging). - Your
render()method is fine.
Final Tip
- If you must throw exceptions outside of controllers, ensure they’re still handled within Laravel’s lifecycle. For edge cases (like jobs/CLI), you may also want to manually catch and suppress/log them as you wish.
Summary:
Change from RuntimeException to Exception, keep your report() method, and Laravel will not log your custom exception.