sergiodxa / remix-auth

Simple Authentication for Remix
https://sergiodxa.github.io/remix-auth/
MIT License
2k stars 110 forks source link

How to display failure #76

Closed JSLNO closed 2 years ago

JSLNO commented 2 years ago

Hey, I want to display the AuthenticationError that is thrown in the login function on the sign in page. Any suggestions on how I could do that or is this even possible?

Thanks

sergiodxa commented 2 years ago

All the strategies catch the errors your throw and wrap it in a Response.

If you defined a failureRedirect, the response would be a redirect and the error will be in the session.

If you didn't defined a failureRedirect, the response will be a 401 with the error as part of the body. This one could be accessed in a CatchBoundary component.

And you can wrap the authenticator.authenticate call in a try/catch and manually check the response and handle the error.

JSLNO commented 2 years ago

All the strategies catch the errors your throw and wrap it in a Response.

If you defined a failureRedirect, the response would be a redirect and the error will be in the session.

If you didn't defined a failureRedirect, the response will be a 401 with the error as part of the body. This one could be accessed in a CatchBoundary component.

And you can wrap the authenticator.authenticate call in a try/catch and manually check the response and handle the error.

I don't get why but when I try using a try/catch block theres always an error thrown even when the credentials are correct. But when I remove the block it works how it is supposed to. Here's the action function I currently have:

export const action: ActionFunction = async ({ request }) => {
    try {
        await authenticator.authenticate('local', request, {
            successRedirect: '/'
        })
    } catch (e) {
        if (e instanceof Response) {
            const data = await e.json()
            return { error: data.message }
        }
        throw e
    }

    return {}
}

This works when the credentials are incorrect, but when they are correct, it throws: FetchError: invalid json response body at reason: Unexpected end of JSON input

sergiodxa commented 2 years ago

That’s because the library made use of Remix ability to throw responses including redirects

JSLNO commented 2 years ago

Sound's interesting, do you have any suggestion on how I could fix it? Thanks

JSLNO commented 2 years ago

Sound's interesting, do you have any suggestion on how I could fix it? Thanks

Okay, I got it working like this:

export const action: ActionFunction = async ({ request }) => {
    try {
        await authenticator.authenticate('local', request, {
            successRedirect: '/'
        })
    } catch (e) {
        console.log(e)
        if (e instanceof Response && e.status === 401) {
            const data = await e.json()

            return {
                error: data.message || 'Unauthorized'
            }
        }
        throw e
    }

    return {}
}