Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

fetch with catch never returns?

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;

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

>Solution :

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.

return await fetch(...)
  .then(
    async (r) => {
      // ...
      redirect(...);
    },
    () => {
      return { success: false, errorMessages: ... }
    }
  );

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).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading