Cannot return custom error to the client side in the Next-Auth v5 Credentials Auth
Provider type
Credentials
Environment
"next": "14.2.3",
"next-auth": "^5.0.0-beta.19",
Reproduction URL
https://github.com/dsmabulage/inventes
Describe the issue
I'm trying to implement the email, password login in the next app using next-auth v5.
In the NextAuth function inside authorize, I tried various methods to throw a custom error message that can passed to the user to show what's going wrong with the credentials.
How to reproduce
export const { auth, handlers, signIn, signOut } = NextAuth({
session: {
strategy: 'jwt',
},
pages: {
signIn: '/auth/login',
},
providers: [
CredentialsProvider({
credentials: {
email: {},
password: {},
},
async authorize({ email, password }) {
try {
throw new Error(
JSON.stringify({ errors: 'user.errors', status: false })
);
} catch (error) {
throw new Error(
JSON.stringify({ errors: ' catch user.errors', status: false })
);
}
},
}),
],
Expected behavior
I want to get that error message to the client side and show that error message to the user.
Hi, I'm facing the same problem. I found this temporary solution that may be helpful: https://github.com/nextauthjs/next-auth/issues/9900#issuecomment-2167681517.
The same issue is being discussed here in detail. I might also tell you that there is a way to check for some error but that also seems to broken currently In previous versions you could do something like this:
import { AuthError } from "next-auth";
import { signIn } from "next-auth/react";
try {
setLoading(true);
setError("");
const res = await signIn("credentials", {
redirect: false,
email,
password,
});
//* The res here has no credentials data only error:true or error:null so we can manage the state based on that
//* Next auth does not send the data due to security reasons
if (res.error === null) {
router.push("/protected");
}
if (res.error) {
setError("Check Your Email Or Password");
}
} catch (error) {
console.error(error.message);
if (error instanceof AuthError) {
switch (error.type) {
case "CredentialsSignin":
console.log("Invalid Password");
setError("Please Check Your Password")
default:
console.log("Something went wrong");
setError("Something went wrong")
}
}
} finally {
setLoading(false);
}
};
The issue with this approach that you do not know if the error is related to credentials like invalid email or something like database connection timeout
The same issue is being discussed here in detail. I might also tell you that there is a way to check for some error but that also seems to broken currently In previous versions you could do something like this:
import { AuthError } from "next-auth"; import { signIn } from "next-auth/react"; try { setLoading(true); setError(""); const res = await signIn("credentials", { redirect: false, email, password, }); //* The res here has no credentials data only error:true or error:null so we can manage the state based on that //* Next auth does not send the data due to security reasons if (res.error === null) { router.push("/protected"); } if (res.error) { setError("Check Your Email Or Password"); } } catch (error) { console.error(error.message); if (error instanceof AuthError) { switch (error.type) { case "CredentialsSignin": console.log("Invalid Password"); setError("Please Check Your Password") default: console.log("Something went wrong"); setError("Something went wrong") } } } finally { setLoading(false); } };The issue with this approach that you do not know if the error is related to credentials like invalid email or something like database connection timeout
Is there a way to throw a custom error message from the authorize method because I have another validation more than checking only the username and password? So that case I need to show different error messages to the client.
we can customize the authorize() function to return custom errors like this https://github.com/nextauthjs/next-auth/pull/9871 And here https://github.com/nextauthjs/next-auth/issues/9099 But to be honest I am not sure how to implement these.
I read somewhere one should be able to throw a new Error with a custom code property (e.g. {code: 'Not verified.'}) and it will be passed to the client. However in 5.0.0-beta.19 it will always return null, {error: 'Configuration', code: null, status: 200, ok: true, url: null}
I read somewhere one should be able to throw a new Error with a custom code property (e.g.
{code: 'Not verified.'}) and it will be passed to the client. However in5.0.0-beta.19it will always returnnull,{error: 'Configuration', code: null, status: 200, ok: true, url: null}
always return null, is it a next-auth issue
https://github.com/nextauthjs/next-auth/issues/11074#issuecomment-2184315761 Follow here for discussions.
Same here I always get these return object even I explicity return an error
https://github.com/nextauthjs/next-auth/issues/11074#issuecomment-2205152161 Please follow this issue for details
This is how i was able to revolve this
In auth.ts or auth.config.ts
create a class that extend theAuthError class
class InvalidLoginError extends AuthError {
code = 'custom';
errorMessage: string;
constructor(message?: any, errorOptions?: any) {
super(message, errorOptions);
this.errorMessage = message;
}
}
then in your credential provider you can use it like
providers: [
Credentials({
async authorize(credentials) {
try {
const response = await axios.post('your-endpoint', {
phone: credentials?.phone,
password: credentials?.password,
});
if (response.data.error) {
throw new InvalidLoginError(response.data.error);
}
const user = response?.data?.data;
if (user) {
return user;
} else {
return null;
}
} catch (e: any) {
throw new InvalidLoginError(e.response?.data?.message);
}
},
}),
],
with this, you can catch the error in your signin api route and also your client signin component
I was able to fix this problem check out in discussions https://github.com/nextauthjs/next-auth/discussions/8999#discussioncomment-10107786
Fixed in #11469