Passing user-friendly NextAuth v5 error messages to the client
In Auth.js v5, you can only pass a custom error message to the client if it's thrown from CredentialSignin's `authorize` function. Here's a workaround for OAuth providers and session/JWT callbacks.
⚠️ Auth.js v5 is still in beta, so the APIs covered in this article are subject to change.
Note: The Next.js package for Auth.js is still called NextAuth. The code examples in this article use NextAuth, but my solution will likely work on other frameworks that Auth.js supports, like SvelteKit, SolidStart, and Qwik.
Background
Recently, I was building a Next.js app with NextAuth. I had to add an OAuth provider with an additional authorization check. However, if the authorization check failed, I found that the client received this obscure error message:
This is hardly user-friendly, so I tried to throw a custom error in my authorization handler:
However, my new error message wasn’t being displayed.
I did some research and came across this GitHub issue
about passing errors to the client from a credential provider’s authorize handler.
The only difference between their situation and mine was that I was using a jwt handler on the user’s first login
instead of implementing my logic with a credentials provider, and
the issue’s proposed solution and
its eventual implementation didn’t support that use case.
The Solution
Note: If you are using a credentials provider and your error-prone logic is in the authorize callback, see this pull request for a built-in solution.
My idea was to add a field on the token when an error occurs that can be checked in middleware or on the client.
Here’s how you can replicate this in your own app.
First, if you’re using TypeScript, augment the JWT and Session interfaces:
Passing The Error to The Client
Then, in your jwt callback, set an error property on the user’s token when an exception is thrown:
Finally, in your session callback, pass the property from the user’s token to their session:
Note: The rest of this guide is Next.js-specific, but the concepts are very similar in the other frameworks that Auth.js supports.
Retrieving and Displaying The Error (Next.js-specific)
Now, you can access the error from the client or in middleware. Here’s a Next.js middleware example:
⚠️ If you create a custom error page as shown in the middleware example, make sure to sign the user out when they visit it!
Otherwise, you may accidentally create an infinite loop that prevents the user from making another sign-in attempt.
If you want to access it on the client, you can write a component like this:
You can use this as a normal React component in your root layout:
Final Note
After writing this, I realized the NextAuth developers used the same pattern in their documentation!
In the section about handling Google refresh tokens,
if there was an error refreshing the user’s access token, the jwt callback sets an error on the user’s token,
which is passed to the user’s session. When the client sees a session with a RefreshAccessTokenError, it
signs the user out.