Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Ligonsker's avatar

Custom error message from LoginController doesn't work

I added a check in LoginController to limit the user's max number of connected devices.

I added the following in the login() method in LoginController :

public function login(Request $request)
{
    // ... some code ...

    if ($this->attemptLogin($request)) {
        $user = Auth::user();
        if ($user->max_devices >= 5) {
            return $this->sendMaxConnectedDevicesResponse($request);
        }
    }

    // ... some code ...
}

protected function sendMaxConnectedDevicesResponse(Request $request)
{
    throw ValidationException::withMessage([
        $this->username() => ['Device limit reached'])
        ->status(403);
}

sendMaxConnectedDevicesResponse is a copy of sendLockoutResponse with my custom message, however I get warning that I have an unhandled exception (Unhandled Illuminate\Validation\ValidationException).

So how can I handle it like sendLockoutResponse handles it, so that it will show as an error in the frontend, instead of just ignoring it? Right now what happens is that even though it throws the error, it doesn't show it in the frontend, and it continues to login as usual

0 likes
10 replies
Snapey's avatar
Snapey
Best Answer
Level 122

and it continues to login as usual

You have already logged in at auth::attempt(). You should logout.

Simplify your code, and name a field that has the validation error

use Illuminate\Validation\ValidationException;

    if ($this->attemptLogin($request)) {
        if (auth()->user()->max_devices >= 5) {
            auth()->logout();
			throw ValidationException::withMessages(['email' => 'Device limit reached']);
        }
    }

1 like
Ligonsker's avatar

@Snapey This is it! thank you. Is there a way to also do it before the user actually logs in? Or I will need to override methods prior to that and manually attempt myself?

Snapey's avatar

@Ligonsker You can find the user by email, and if ok, then do Auth::attempt

1 like
Ligonsker's avatar

@Snapey I checked but I am not sure - looks like the code that Laravel Auth uses for finding the user before the attempt is done somewhere in the Stateful Guard? I just couldn't find the code itself. Do you know how Laravel does that so that I try to do it as close to source as possible? I don't want to miss some checks

Snapey's avatar

@Ligonsker Do you have more than one guard? If not, why worry about it.

    if($user=User::where('email', $request->email)->first()) {
         if ($user->max_devices >= 5) {
			throw ValidationException::withMessages(['email' => 'Device limit reached']);
        }

    	$this->attemptLogin($request);
    }

1 like
Ligonsker's avatar

@Snapey thank you! I probably don't have more than one guard, but now I'm curious, do you have more information where I can see more about multiple guards, as I've never even thought about using it? So just for my knowledge. So now "guard" is a black box which I never touched, just setup the auth and go

Snapey's avatar

@Ligonsker guards are meant as providers for multiple different ways of logging in, but some people misuse them to provide different login routes for different types of user.

If you don't know about guards then you will be using the default web guard.

1 like

Please or to participate in this conversation.