diff --git a/src/libs/API.js b/src/libs/API.js index 94b48e42b454..6a85e599b95f 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -182,6 +182,10 @@ Network.registerResponseHandler((queuedRequest, response) => { }); Network.registerErrorHandler((queuedRequest, error) => { + if (error.name === 'AbortError') { + Log.info('[API] request aborted', false, queuedRequest); + return; + } if (queuedRequest.command !== 'Log') { Log.hmmm('[API] Handled error when making request', error); } else { diff --git a/src/libs/HttpUtils.js b/src/libs/HttpUtils.js index f9a33ea4be05..57924f472250 100644 --- a/src/libs/HttpUtils.js +++ b/src/libs/HttpUtils.js @@ -10,19 +10,24 @@ Onyx.connect({ callback: val => shouldUseSecureStaging = (val && _.isBoolean(val.shouldUseSecureStaging)) ? val.shouldUseSecureStaging : false, }); +const NON_ABORTABLE_COMMANDS = ['Log', 'DeleteLogin']; +let abortController = new AbortController(); + /** * Send an HTTP request, and attempt to resolve the json response. * If there is a network error, we'll set the application offline. * * @param {String} url - * @param {String} method - * @param {Object} body + * @param {String} [method='get'] + * @param {Object} [body=null] + * @param {Boolean} [canAbort=true] * @returns {Promise} */ -function processHTTPRequest(url, method = 'get', body = null) { +function processHTTPRequest(url, method = 'get', body = null, canAbort = true) { return fetch(url, { method, body, + signal: canAbort ? abortController.signal : undefined, }) .then(response => response.json()); } @@ -44,7 +49,9 @@ function xhr(command, data, type = CONST.NETWORK.METHOD.POST, shouldUseSecure = apiRoot = CONST.STAGING_SECURE_URL; } - return processHTTPRequest(`${apiRoot}api?command=${command}`, type, formData); + const canAbort = !_.contains(NON_ABORTABLE_COMMANDS, command); + + return processHTTPRequest(`${apiRoot}api?command=${command}`, type, formData, canAbort); } /** @@ -64,7 +71,13 @@ function download(relativePath) { return processHTTPRequest(`${siteRoot}${strippedRelativePath}`); } +function abortPendingRequests() { + abortController.abort(); + abortController = new AbortController(); +} + export default { download, xhr, + abortPendingRequests, }; diff --git a/src/libs/actions/SignInRedirect.js b/src/libs/actions/SignInRedirect.js index 95e8b862d8bc..1b05c13b65d8 100644 --- a/src/libs/actions/SignInRedirect.js +++ b/src/libs/actions/SignInRedirect.js @@ -1,6 +1,7 @@ import Onyx from 'react-native-onyx'; import SignoutManager from '../SignoutManager'; import ONYXKEYS from '../../ONYXKEYS'; +import HttpUtils from '../HttpUtils'; let currentActiveClients; Onyx.connect({ @@ -20,6 +21,7 @@ Onyx.connect({ * @param {String} errorMessage */ function clearStorageAndRedirect(errorMessage) { + HttpUtils.abortPendingRequests(); const activeClients = currentActiveClients; const preferredLocale = currentPreferredLocale;