Reputation: 21
I have a client component Form (activate-form.tsx
) for new users to attach a username and name to their account when they first log in and authorize the app via NextAuth's Google OAuth provider.
I'm using Next.js, and the Form calls the server action (activate()
) in an onSubmit handler which then calls NextAuth's signIn()
function.
activate-form.tsx
// activate-form.tsx
// ...some code
const onSubmit: SubmitHandler<FormValues> = (values) => {
const { username, name } = values;
startTransition(() => {
actions.activate(username, name).then((res) => {
setError(res?.error);
});
});
};
return (
// ...some addtl code
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
// ...rest of the Form
/>
</Form>
);
auth.ts - this is a separate file for my auth-related server actions
// auth.ts
// ...some code
export const activate = async (username: string, name: string) => {
cookies().set('username', username);
cookies().set('name', name);
try {
await auth.signIn('google');
} catch (error: any) {
if (error instanceof Error) {
return {
error: error.message, // ** <== THIS IS WHERE NEXT_REDIRECT GETS RETURNED TO THE FORM **
};
}
}
};
The signIn()
function comes from NextAuth after initializing it with the PrismaAdapter.
The problem - I'm trying to catch errors that arise from the NextAuth signIn flow and return error.message
to the Form where it can display the corresponding message from the actual error. But when an error gets caught, rather than giving me the expected error.message
, I'm getting ”NEXT_REDIRECT”
.
For example, I want to override PrismaAdapter's createUser
function so that I can execute some logic before creating the user. If i just throw any error in there, I expect to catch it from the signIn() call inside my server action, but I still get the “NEXT_REDIRECT” as the error message.
export const {
handlers: { GET, POST },
auth,
signIn,
signOut,
} = NextAuth((req) => ({
adapter: {
...PrismaAdapter(db),
async createUser(user) {
throw new Error('testing testing'); <=== THROWN TO SEE IF SERVER ACTION PICKS IT UP
// ...plan to add more logic here
return user;
},
},
What's weird is that although error.message
is “NEXT_REDIRECT” when I console.log it inside the catch block of the server action, if I were to instead re-throw the error I'm actually able to see the expected error and message in the server logs.
modified auth.ts
export const activate = async (username: string, name: string) => {
cookies().set('username', username);
cookies().set('name', name);
try {
await auth.signIn('google');
} catch (error: any) {
if (error instanceof Error) {
throw error // ** <=== RETHROW ERROR INSTEAD OF RETURNING IT
}
}
};
Notice how AdapterError
is showing along with the "testing testing" message from the error thrown from the createUser
function.
Why is it that when I rethrow the error it's correct, but when I log it inside the server action I just get “NEXT_REDIRECT”? And how can I get the proper message back to the Form?
Upvotes: 0
Views: 55