Since adding a catch handler to my fetch in the rare case that the server is offline or unreachable, it never returns. Execution is never broke, end point hit. I don’t get any response from my form action, no messages are displayed, and the redirect is never hit, although all scopes are reachable.
If I reload after its executed, I have my cookie and can reach /home, it just doesn’t redirect or return any validation on failure.
Here is my login action;
export const actions = {
login: async ({ cookies, request }) => {
const data = await request.formData();
const objectData = Object.fromEntries(data.entries());
const schemaCheck = schema.safeParse(objectData);
if (!schemaCheck.success) {
return { success: false, errorMessages: schemaCheck.error.errors.map((error) => {
return error.message
})}
}
await fetch(PUBLIC_API_URL + '/auth/login', {
method: "POST",
body: JSON.stringify(objectData)
})
.then(async (r) => {
const json = await r.json()
if (Object.prototype.hasOwnProperty.call(json, 'error_message')) {
return { success: false, errorMessages: [json['error_message']] };
}
cookies.set('session', json.access_token, { path: '/' });
redirect(303, '/home');
})
.catch(() => {
return { success: false, errorMessages: ['Something went wrong, try again later.']}
})
console.log('hello');
}
};
If I remove the continuation and exception handler, it works fine.
2
Answers
You shouldn’t mix
await
with.then
or.catch
. The reason it doesn’t terminate the login function is because thereturn
is in another function scope.You could try something like this instead:
The
catch
block also catches errors caused inawait fetch
, so if your API didn’t work, it will also go to thecatch
block.The returns are inside a nested function, you would need to
return await fetch(...)
to get the result out of there.redirect
works by throwing an exception, if you just catch that again, this will never work.You could probably restructure this by using the second
then
argument, which does not catch errors thrown in the success callback.You could also avoid the chaining syntax, but you would have to work around
redirect
using an exception (e.g. catch and re-throw it).