From 3d78f7295ac394134bee4468eda3a9d303a79ac6 Mon Sep 17 00:00:00 2001 From: Tomasz Lesniakiewicz Date: Tue, 13 Jan 2026 13:18:19 +0100 Subject: [PATCH 1/3] unblock networ queue and sen aurh error to sentry --- src/libs/Authentication.ts | 15 +++++++++++++++ src/libs/telemetry/trackAuthenticationError.ts | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/libs/Authentication.ts b/src/libs/Authentication.ts index 51dcf99b42cd0..1f58ea7deef44 100644 --- a/src/libs/Authentication.ts +++ b/src/libs/Authentication.ts @@ -208,6 +208,21 @@ function reauthenticate(command = ''): Promise { }); return true; + }).catch((error) => { + // Ensure we always unblock the network queue, even on unexpected errors + setIsAuthenticating(false); + + trackAuthenticationError(error as Error, { + errorType: 'unexpected_error', + functionName: 'reauthenticate', + command, + }); + + Log.alert('Reauthenticate - Unexpected error during authentication', { + error: (error as Error).message, + command, + }); + throw error; }); }); } diff --git a/src/libs/telemetry/trackAuthenticationError.ts b/src/libs/telemetry/trackAuthenticationError.ts index 08438b776e94b..c8b98ae010ffb 100644 --- a/src/libs/telemetry/trackAuthenticationError.ts +++ b/src/libs/telemetry/trackAuthenticationError.ts @@ -2,7 +2,7 @@ import * as Sentry from '@sentry/react-native'; import CONST from '@src/CONST'; type AuthenticationFunction = 'Authenticate' | 'reauthenticate'; -type AuthenticationErrorType = 'missing_params' | 'network_retry' | 'auth_failure'; +type AuthenticationErrorType = 'missing_params' | 'network_retry' | 'auth_failure' | 'unexpected_error'; type AuthenticationErrorContext = { errorType: AuthenticationErrorType; From f397708c4e2d866576ca8af397ba817e417e965f Mon Sep 17 00:00:00 2001 From: Tomasz Lesniakiewicz Date: Wed, 14 Jan 2026 15:56:10 +0100 Subject: [PATCH 2/3] chore: priettier format --- src/libs/Authentication.ts | 142 +++++++++++++++++++------------------ 1 file changed, 72 insertions(+), 70 deletions(-) diff --git a/src/libs/Authentication.ts b/src/libs/Authentication.ts index 1f58ea7deef44..594b868d59364 100644 --- a/src/libs/Authentication.ts +++ b/src/libs/Authentication.ts @@ -142,88 +142,90 @@ function reauthenticate(command = ''): Promise { partnerPassword, partnerUserID: credentials?.autoGeneratedLogin, partnerUserSecret: credentials?.autoGeneratedPassword, - }).then((response) => { - if (!response) { - return false; - } + }) + .then((response) => { + if (!response) { + return false; + } - Log.hmmm('Reauthenticate - Processing authentication result', { - command, - }); - - if (response.jsonCode === CONST.JSON_CODE.UNABLE_TO_RETRY) { - // When a fetch() fails due to a network issue and an error is thrown we won't log the user out. Most likely they - // have a spotty connection and will need to retry reauthenticate when they come back online. Error so it can be handled by the retry mechanism. - const error = new Error('Unable to retry Authenticate request'); - trackAuthenticationError(error, { - errorType: 'network_retry', - functionName: 'reauthenticate', - jsonCode: response.jsonCode, + Log.hmmm('Reauthenticate - Processing authentication result', { command, }); - throw error; - } - // If authentication fails and we are online then log the user out - if (response.jsonCode !== 200) { - const errorMessage = getAuthenticateErrorMessage(response); + if (response.jsonCode === CONST.JSON_CODE.UNABLE_TO_RETRY) { + // When a fetch() fails due to a network issue and an error is thrown we won't log the user out. Most likely they + // have a spotty connection and will need to retry reauthenticate when they come back online. Error so it can be handled by the retry mechanism. + const error = new Error('Unable to retry Authenticate request'); + trackAuthenticationError(error, { + errorType: 'network_retry', + functionName: 'reauthenticate', + jsonCode: response.jsonCode, + command, + }); + throw error; + } + + // If authentication fails and we are online then log the user out + if (response.jsonCode !== 200) { + const errorMessage = getAuthenticateErrorMessage(response); + + trackAuthenticationError(new Error('Authentication failed'), { + errorType: 'auth_failure', + functionName: 'reauthenticate', + jsonCode: response.jsonCode, + command, + errorMessage, + }); + setIsAuthenticating(false); + Log.hmmm('Redirecting to Sign In because we failed to reauthenticate', { + command, + error: errorMessage, + }); + redirectToSignIn(errorMessage); + return false; + } + + // If we reauthenticate due to an expired delegate token, restore the delegate's original account. + // This is because the credentials used to reauthenticate were for the delegate's original account, and not for the account they were connected as. + if (isConnectedAsDelegate({delegatedAccess: account?.delegatedAccess})) { + Log.info('Reauthenticate while connected as a delegate. Restoring original account.'); + restoreDelegateSession(response); + return true; + } + + // Update authToken in Onyx and in our local variables so that API requests will use the new authToken + updateSessionAuthTokens(response.authToken, response.encryptedAuthToken); + + // Note: It is important to manually set the authToken that is in the store here since any requests that are hooked into + // reauthenticate .then() will immediate post and use the local authToken. Onyx updates subscribers lately so it is not + // enough to do the updateSessionAuthTokens() call above. + setAuthToken(response.authToken ?? null); + + // The authentication process is finished so the network can be unpaused to continue processing requests + setIsAuthenticating(false); - trackAuthenticationError(new Error('Authentication failed'), { - errorType: 'auth_failure', - functionName: 'reauthenticate', - jsonCode: response.jsonCode, + Log.hmmm('Reauthenticate - Re-authentication successful', { command, - errorMessage, }); + + return true; + }) + .catch((error) => { + // Ensure we always unblock the network queue, even on unexpected errors setIsAuthenticating(false); - Log.hmmm('Redirecting to Sign In because we failed to reauthenticate', { + + trackAuthenticationError(error as Error, { + errorType: 'unexpected_error', + functionName: 'reauthenticate', command, - error: errorMessage, }); - redirectToSignIn(errorMessage); - return false; - } - - // If we reauthenticate due to an expired delegate token, restore the delegate's original account. - // This is because the credentials used to reauthenticate were for the delegate's original account, and not for the account they were connected as. - if (isConnectedAsDelegate({delegatedAccess: account?.delegatedAccess})) { - Log.info('Reauthenticate while connected as a delegate. Restoring original account.'); - restoreDelegateSession(response); - return true; - } - - // Update authToken in Onyx and in our local variables so that API requests will use the new authToken - updateSessionAuthTokens(response.authToken, response.encryptedAuthToken); - // Note: It is important to manually set the authToken that is in the store here since any requests that are hooked into - // reauthenticate .then() will immediate post and use the local authToken. Onyx updates subscribers lately so it is not - // enough to do the updateSessionAuthTokens() call above. - setAuthToken(response.authToken ?? null); - - // The authentication process is finished so the network can be unpaused to continue processing requests - setIsAuthenticating(false); - - Log.hmmm('Reauthenticate - Re-authentication successful', { - command, - }); - - return true; - }).catch((error) => { - // Ensure we always unblock the network queue, even on unexpected errors - setIsAuthenticating(false); - - trackAuthenticationError(error as Error, { - errorType: 'unexpected_error', - functionName: 'reauthenticate', - command, - }); - - Log.alert('Reauthenticate - Unexpected error during authentication', { - error: (error as Error).message, - command, + Log.alert('Reauthenticate - Unexpected error during authentication', { + error: (error as Error).message, + command, + }); + throw error; }); - throw error; - }); }); } From 579e7fa96e29fbbef217e26da72a761143af19b1 Mon Sep 17 00:00:00 2001 From: Tomasz Lesniakiewicz Date: Thu, 15 Jan 2026 15:13:40 +0100 Subject: [PATCH 3/3] remove the manual unblocking the queue on unexpected error --- src/libs/Authentication.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libs/Authentication.ts b/src/libs/Authentication.ts index 594b868d59364..abbbf8407105d 100644 --- a/src/libs/Authentication.ts +++ b/src/libs/Authentication.ts @@ -211,9 +211,6 @@ function reauthenticate(command = ''): Promise { return true; }) .catch((error) => { - // Ensure we always unblock the network queue, even on unexpected errors - setIsAuthenticating(false); - trackAuthenticationError(error as Error, { errorType: 'unexpected_error', functionName: 'reauthenticate',