Skip to content

Commit

Permalink
release(required): network error has not been properly detected (#13935)
Browse files Browse the repository at this point in the history
* fix(core): retry is not applied on network error

* fix(auth): wrongly clear tokens on network error when refresh tokens

* chore(aws-amplify): bump list bundle size limits
  • Loading branch information
HuiSF authored Oct 25, 2024
1 parent 3f8451c commit da62f57
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import {
AmplifyError,
AmplifyErrorCode,
} from '@aws-amplify/core/internals/utils';

import { tokenOrchestrator } from '../../../../src/providers/cognito/tokenProvider';
import { CognitoAuthTokens } from '../../../../src/providers/cognito/tokenProvider/types';
import { oAuthStore } from '../../../../src/providers/cognito/utils/oauth/oAuthStore';

jest.mock('@aws-amplify/core/internals/utils');
jest.mock('@aws-amplify/core', () => ({
...jest.requireActual('@aws-amplify/core'),
Hub: {
Expand Down Expand Up @@ -90,4 +94,20 @@ describe('tokenOrchestrator', () => {
expect(newTokens?.signInDetails).toEqual(testSignInDetails);
});
});

describe('handleErrors method', () => {
it('does not call clearTokens() if the error is a network error thrown from fetch handler', () => {
const clearTokensSpy = jest.spyOn(tokenOrchestrator, 'clearTokens');
const error = new AmplifyError({
name: AmplifyErrorCode.NetworkError,
message: 'Network Error',
});

expect(() => {
(tokenOrchestrator as any).handleErrors(error);
}).toThrow(error);

expect(clearTokensSpy).not.toHaveBeenCalled();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from '@aws-amplify/core';
import {
AMPLIFY_SYMBOL,
AmplifyErrorCode,
assertTokenProviderConfig,
isBrowser,
isTokenExpired,
Expand Down Expand Up @@ -169,7 +170,7 @@ export class TokenOrchestrator implements AuthTokenOrchestrator {

private handleErrors(err: unknown) {
assertServiceError(err);
if (err.message !== 'Network error') {
if (err.name !== AmplifyErrorCode.NetworkError) {
// TODO(v6): Check errors on client
this.clearTokens();
}
Expand Down
2 changes: 1 addition & 1 deletion packages/aws-amplify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@
"name": "[Storage] list (S3)",
"path": "./dist/esm/storage/index.mjs",
"import": "{ list }",
"limit": "15.41 kB"
"limit": "15.50 kB"
},
{
"name": "[Storage] remove (S3)",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { HttpResponse } from '../../../../src/clients';
import { getRetryDecider } from '../../../../src/clients/middleware/retry/defaultRetryDecider';
import { AmplifyError } from '../../../../src/errors';
import { AmplifyErrorCode } from '../../../../src/types';

describe('getRetryDecider', () => {
const mockErrorParser = jest.fn();

describe('created retryDecider', () => {
const mockNetworkErrorThrownFromFetch = new AmplifyError({
name: AmplifyErrorCode.NetworkError,
message: 'Network Error',
});
const mockNetworkErrorThrownFromXHRInStorage = new Error('Network Error');
mockNetworkErrorThrownFromXHRInStorage.name = 'ERR_NETWORK';
mockNetworkErrorThrownFromXHRInStorage.message = 'Network Error';

test.each([
[
'a network error from the fetch handler',
true,
mockNetworkErrorThrownFromFetch,
],
[
'a network error from the XHR handler defined in Storage',
true,
mockNetworkErrorThrownFromXHRInStorage,
],
])('when receives %p returns %p', (_, expected, error) => {
const mockResponse = {} as unknown as HttpResponse;
mockErrorParser.mockReturnValueOnce(error);
const retryDecider = getRetryDecider(mockErrorParser);

expect(retryDecider(mockResponse, error)).resolves.toBe(expected);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { AmplifyErrorCode } from '../../../types';
import { ErrorParser, HttpResponse } from '../../types';

import { isClockSkewError } from './isClockSkewError';
Expand Down Expand Up @@ -55,7 +56,11 @@ const isThrottlingError = (statusCode?: number, errorCode?: string) =>
(!!errorCode && THROTTLING_ERROR_CODES.includes(errorCode));

const isConnectionError = (error?: unknown) =>
(error as Error)?.name === 'Network error';
[
AmplifyErrorCode.NetworkError,
// TODO(vNext): unify the error code `ERR_NETWORK` used by the Storage XHR handler
'ERR_NETWORK',
].includes((error as Error)?.name);

const isServerSideError = (statusCode?: number, errorCode?: string) =>
(!!statusCode && [500, 502, 503, 504].includes(statusCode)) ||
Expand Down

0 comments on commit da62f57

Please sign in to comment.