aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.43k stars 2.13k forks source link

fetchAuthSession error: "An unknown error has occurred" #13486

Open ronbhomri opened 5 months ago

ronbhomri commented 5 months ago

Before opening, please confirm:

JavaScript Framework

React

Amplify APIs

Authentication

Amplify Version

v6

Amplify Categories

auth

Backend

CDK

Environment information

``` # Put output below this line ```

Describe the bug

We use fetchAuthSession with forceRefresh = true when we want to get a new access token. Sometimes, we get this error from the fetchAuthSession function: “An unknown error has occurred”. we tried to dive into this, and we saw the ‘underlyingError’ is “Network error”.

We also have an event listener on network connection, and it’s not triggering when we get the Network error from Amplify, so we’re unsure if it’s a real network issue.

We can also see in the users recording the request was sent to Cognito, but there is no response. There other weird issue is that sometimes before the ‘fetchAuthSession’ we call ‘updateUserAttribute’ and that is working, but the refresh getting this error I mentioned above.

What is expected from the app to do in this case? logout? refresh the page? wait for internet connection?

Expected behavior

The expected behavior is that this error will be more clear, and that if its network error, there will be a retry when the connection is back.

Reproduction steps

We didn't managed to reproduce, happens randomly.

Code Snippet

export const fetchSession = async ({ forceRefresh = true }: { forceRefresh?: boolean }) => {
  try {
    return await Auth.fetchAuthSession({ forceRefresh });
  } catch (error) {
    new Error(`Fetch session error: ${(error as any).message} ${(error as any).underlyingError} `);
  }
}

Log output

``` // Put your logs below this line ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

cwomack commented 5 months ago

Hello, @ronbhomri and thanks for opening this issue. Can you clarify what version of Amplify you're on or share your package.json file?

There have been recent issues opened to a bug introduced with fetchAuthSession() (see #13456 and #13472), but both of those were using SSR and Next.JS with a fix released recently. This is happening with a basic React frontend it looks like. Are you calling fetchAuthSession() within a useEffect hook? Or can you share any additional frontend code that details your Auth flows? Thanks!

HuiSF commented 5 months ago

Hi @ronbhomri Thanks for reporting this issue. Could you provide more information to help us triaging this issue?

We use fetchAuthSession with forceRefresh = true when we want to get a new access token. Sometimes, we get this error from the fetchAuthSession function: “An unknown error has occurred”. we tried to dive into this, and we saw the ‘underlyingError’ is “Network error”.

Is this happening when there were many concurrent requests that requested fetchAuthSession({ forceRefresh: true})? Are you executing this logic on the client side of a React SPA or on the server side with Next.js?

await Auth.fetchAuthSession({ forceRefresh })

Looking this line, are you using Amplify v6? Could you paste the complete code snippet?

We also have an event listener on network connection, and it’s not triggering when we get the Network error from Amplify, so we’re unsure if it’s a real network issue.

Could you provide the detail of this event listener you mentioned here, and how did you add it?

ronbhomri commented 5 months ago

@cwomack the version is 6.0.12 we are not using useEffect, we are using useQuery which trigger the function after 5 minutes, to proactive refresh the token.

Lirontal1 commented 5 months ago

Hi @cwomack , Liron here, from @ronbhomri's team. Our platform utilizes a "proactive token" strategy. our idToken expiration duration is 5minutes, so we proactively refresh the id token about 30 seconds before the current id token is expired. The idToken code generation is (more or less) as follows:

  await Auth.updateUserAttributes({
      userAttributes: {
        'custom:org_id': '1234',
      },
    });
try {
    return await Auth.fetchAuthSession({ forceRefresh: true });
  } catch (error) {
    console.error(`[authentication error]: Fetch session error: ${(error as any).message} ${(error as any).underlyingError} `);
    if ((error as any).message?.includes('An unknown error has occurred')) {
      // Log out the user
    }
    return {};
  }

In the first part we update a Cognito user attribute for the user. not sure if it's related, but just putting it here (if you think it's. related to this let me know, I'll give more details). In the second part we try to retrieve the new idToken, while using forceRefresh (so it will not use the browser's cache). This is where it fails for us with the network error. it's really odd that it happens there because:

  1. Just before it we update the user attribute, which is also async request via Amplify API, so how does the first succeeds while the other does not?

  2. As Ron described, we have an event listener for network connectivity. as we see in our recordings, when users get the network error from Amplify, we don't see the snackbar we show when this event listener is triggered. as for implementation, we're using navigator.onOnline document object to know whether the user is online (we show a snackbar so we should see it in the recording)

  3. Our current implementaion logs out the user when he gets a network error. we see in the recording that the users always manage to login back immediately afterwards, so it's highly unlikely they all had internet issues for 1 second during the token refresh and then immediately back to normal

App is based on React, powered by Vite.

Please let us know if we can provide any more details.

cwomack commented 5 months ago

@Lirontal1, are you able to share a minimal sample repo that can reproduce this or further details on the business logic for item bullet point number 3 in your comment above? And can you provide the entire object of the underlying error as well?

Lirontal1 commented 5 months ago

This is a sample repo with all the relevant parts of our code For reproducing it we found that switching between WIFIs does it, but due to the reasons I stated above, we aren't sure it's always because of unavailable connection. The sample should also includes the logout logic I've described in bullet #3. we're both not sure if logout the user is the right approach (maybe we should add a retry / setTimeout logic?) and also not sure why it works from all users straight up after it logs them out (meaning they likely had internet connection)

israx commented 5 months ago

hello @Lirontal1 . I'm getting Sandbox not found when trying to access the provided link.

Lirontal1 commented 5 months ago

please try now, @israx

israx commented 5 months ago

hello @Lirontal1 . After digging into the issue I was able to see that the underlying error is raised by a TypeError: Failed to fetch error coming from the fetch API. This error can be caused due to:

Thanks to the provided App I was able to reproduce this error on the following scenarios:

  1. closing laptop, opening it again and making a request
  2. switching over networks and making a request

On both cases I see that there is a delay when connecting to the network. In that situation, you can add some retry logic until the connection is back.

ronbhomri commented 5 months ago

@israx we will add it on our side, but maybe you should add some retry mechanism on your side as well, since I believe more users will encounter this error

Lirontal1 commented 5 months ago

Yes, maybe it should be a conditional parameter^

israx commented 5 months ago

Thanks @Lirontal1 and @ronbhomri for the feedback, we will consider that as a feature request, and please let us know if the workaround ended up working.

sidraval commented 4 months ago

I wanted to mention that we're running into the same issue – adding retry logic has helped, though it's still not 100%. We recently upgraded to aws-amplify from amazon-cognito-identity-js – we did not experience this issue with the cognito-identity-js library.

haverchuck commented 4 months ago

@Lirontal1 and @ronbhomri Did the workaround help you out?

donaldpipowitch commented 4 months ago

It would be nice if "An unknown error has occurred." could be more descriptive/specific (e.g. flagging network errors).

ronbhomri commented 4 months ago

@haverchuck it helps some of the cases, but it would be nice if this was handled in Amplify