import axios from 'axios'; import { Dispatch } from '@reduxjs/toolkit'; import { toast } from '../../../RN-UI-LIB/src/components/toast'; import { getCurrentScreen } from './navigationUtlis'; import { GLOBAL } from '../../constants/Global'; import { _map, compareUrl } from '../../../RN-UI-LIB/src/utlis/common'; import { BASE_AV_APP_URL } from '../../constants/config'; import { logError } from './errorUtils'; import { addClickstreamEvent, sendApiToClickstreamEvent, } from '../../services/clickstreamEventService'; import { handleLogout } from '../../action/authActions'; import { API_ERROR_MESSAGE, CLICKSTREAM_EVENT_NAMES, REQUEST_TO_UNBLOCK_FOR_IMPERSONATION, REQUEST_TYPE_TO_BLOCK_FOR_IMPERSONATION, } from '../../common/Constants'; import { ToastMessages } from '../../screens/allCases/constants'; import { alfredHandleSWWEvent } from './DeviceUtils'; import { setWithinOperativeHours } from '@reducers/userSlice'; import store from '@store'; export enum ApiKeys { GENERATE_OTP = 'GENERATE_OTP', VERIFY_OTP = 'VERIFY_OTP', ALL_CASES = 'ALL_CASES', CASE_DETAIL = 'CASE_DETAIL', PINNED_CASES = 'PINNED_CASES', PINNED_CASES_V2 = 'PINNED_CASES_V2', LOGOUT = 'LOGOUT', FEEDBACK = 'FEEDBACK', FILTERS = 'FILTERS', JANUS = 'JANUS', GENERATE_PAYMENT_LINK = 'GENERATE_PAYMENT_LINK', GENERATE_PAYMENT_LINK_V2 = 'GENERATE_PAYMENT_LINK_V2', ADDRESSES_GEOLOCATION = 'ADDRESSES_GEOLOCATION', NEW_ADDRESS = 'NEW_ADDRESS', GET_SIGNED_URL = 'GET_SIGNED_URL', CASE_UNIFIED_DETAILS = 'CASE_UNIFIED_DETAILS', CASE_UNIFIED_DETAILS_V4 = 'CASE_UNIFIED_DETAILS_V4', UNGROUPED_ADDRESSES = 'UNGROUPED_ADDRESSES', PAST_FEEDBACK = 'PAST_FEEDBACK', PAST_FEEDBACK_ON_ADDRESSES = 'PAST_FEEDBACK_ON_ADDRESSES', NOTIFICATIONS = 'NOTIFICATIONS', NOTIFICATION_ACTION = 'NOTIFICATION_ACTION', NOTIFICATION_DELIVERED = 'NOTIFICATION_DELIVERED', SEND_LOCATION = 'SEND_LOCATION', VERIFY_GOOGLE_SIGN_IN = 'VERIFY_GOOGLE_SIGN_IN', SYNC_TIME = 'SYNC_TIME', IS_DATA_SYNC_REQUIRED = 'IS_DATA_SYNC_REQUIRED', GET_PRE_SIGNED_URL_DATA_SYNC = 'GET_PRE_SIGNED_URL_DATA_SYNC', DATA_SYNC_UPLOAD_COMPLETED = 'DATA_SYNC_UPLOAD_COMPLETED', IMPERSONATION = 'IMPERSONATION', TELEPHONES = 'TELEPHONES', CASES_SYNC_STATUS = 'CASES_SYNC_STATUS', CASES_SEND_ID = 'CASES_SEND_ID', FETCH_CASES = 'FETCH_CASES', GET_FORECLOSURE_AMOUNT = 'GET_FORECLOSURE_AMOUNT', UPLOAD_FEEDBACK_IMAGES = 'UPLOAD_FEEDBACK_IMAGES', ORIGINAL_IMAGES = 'ORIGINAL_IMAGES', GLOBAL_CONFIG = 'GLOBAL_CONFIG', UPLOAD_IMAGE_ID = 'UPLOAD_IMAGE_ID', GET_DOCUMENTS = 'GET_DOCUMENTS', REPORTEES = 'REPORTEES', GET_AGENT_DETAIL = 'GET_AGENT_DETAIL', GET_SIGNED_URL_FOR_REPORTEE = 'GET_SIGNED_URL_FOR_REPORTEE', GET_PERFORMANCE_METRICS = 'GET_PERFORMANCE_METRICS', GET_CASH_COLLECTED = 'GET_CASH_COLLECTED', GET_TELEPHONE_NUMBERS = 'GET_TELEPHONE_NUMBERS', GET_TELEPHONE_NUMBERS_V2 = 'GET_TELEPHONE_NUMBERS_V2', FIRESTORE_INCONSISTENCY_INFO = 'FIRESTORE_INCONSISTENCY_INFO', FIRESTORE_INCONSISTENCY_INFO_V2 = 'FIRESTORE_INCONSISTENCY_INFO_V2', GET_CASE_DETAILS_FROM_API = 'GET_CASE_DETAILS_FROM_API', GET_CASE_DETAILS_FROM_API_V2 = 'GET_CASE_DETAILS_FROM_API_V2', DAILY_COMMITMENT = 'DAILY_COMMITMENT', GET_PTP_AMOUNT = 'GET_PTP_AMOUNT', GET_VISIBILITY_STATUS = 'GET_VISIBILITY_STATUS', GET_CSA_TICKETS = 'GET_CSA_TICKETS', GET_CSA_SINGLE_TICKET = 'GET_CSA_SINGLE_TICKET', CREATE_TICKET = 'CREATE_TICKET', ACKNOWLEDGE_TICKET = 'ACKNOWLEDGE_TICKET', ADD_COMMENT = 'ADD_COMMENT', UPDATE_TICKET_STATUS = 'UPDATE_TICKET_STATUS', GET_CSA_FILTERS = 'GET_CSA_FILTERS', GET_FORM_OPTIONS = 'GET_FORM_OPTIONS', GET_UPDATE_COUNT = 'GET_UPDATE_COUNT', SIMILAR_GEOLOCATION_TIMESTAMPS = 'SIMILAR_GEOLOCATION_TIMESTAMPS', GET_PRE_SIGNED_URL = 'GET_PRE_SIGNED_URL', SEND_UPLOAD_ACK = 'SEND_UPLOAD_ACK', DUE_AMOUNT_SUMMARY = 'DUE_AMOUNT_SUMMARY', FEE_WAIVER_HISTORY = 'FEE_WAIVER_HISTORY', FEE_WAIVER_V2 = 'FEE_WAIVER_V2', GET_PIN_CODES_DETAILS = 'GET_PIN_CODES_DETAILS', SYNC_COSMOS_TO_LONGHORN = 'SYNC_COSMOS_TO_LONGHORN', CALL_CUSTOMER = 'CALL_CUSTOMER', SYNC_ACTIVE_CALL_DETAILS = 'SYNC_ACTIVE_CALL_DETAILS', GET_CALL_HISTORY = 'GET_CALL_HISTORY', FETCH_CUSTOMER_DOCUMENTS = 'FETCH_CUSTOMER_DOCUMENTS', FETCH_AGENT_DOCUMENTS = 'FETCH_AGENT_DOCUMENTS', FETCH_DOCUMENT_SPECIFIC_LANGUAGE = 'FETCH_DOCUMENT_SPECIFIC_LANGUAGE', SEND_COMMUNICATION_NAVI_ACCOUNT = 'SEND_COMMUNICATION_NAVI_ACCOUNT', SYNC_CALL_FEEDBACK_NUDGE_DETAILS = 'SYNC_CALL_FEEDBACK_NUDGE_DETAILS', GENERATE_DYNAMIC_DOCUMENT = 'GENERATE_DYNAMIC_DOCUMENT', DOWNLOAD_LATEST_APP = 'DOWNLOAD_LATEST_APP', GET_SIGNED_URL_V2 = 'GET_SIGNED_URL_V2', GET_SIGNED_URL_FOR_REPORTEE_V2 = 'GET_SIGNED_URL_FOR_REPORTEE_V2', ALL_ESCALATIONS = 'ALL_ESCALATIONS', GET_UNGROUPED_ADDRESSES = 'GET_UNGROUPED_ADDRESSES', GET_GROUPED_ADDRESSES_AND_GEOLOCATIONS = 'GET_GROUPED_ADDRESSES', GET_EMI_SCHEDULE = 'GET_EMI_SCHEDULE', GET_REPAYMENTS = 'GET_REPAYMENTS', GET_FEEDBACK_HISTORY = 'GET_FEEDBACK_HISTORY', GET_PRIORTIY_FEEDBACK = 'GET_PRIORTIY_FEEDBACK', GET_TRAINING_MATERIAL_LIST = 'GET_TRAINING_MATERIAL_LIST', GET_TRAINING_MATERIAL_DETAILS = 'GET_TRAINING_MATERIAL_DETAILS', SELF_CALL_ACK= '/api/v1/self-call' } export const API_URLS: Record = {} as Record; API_URLS[ApiKeys.GENERATE_OTP] = '/auth/request-otp'; API_URLS[ApiKeys.VERIFY_OTP] = '/auth/otp/verify'; API_URLS[ApiKeys.ALL_CASES] = '/cases/all-cases'; API_URLS[ApiKeys.CASE_DETAIL] = '/cases/get-cases'; API_URLS[ApiKeys.PINNED_CASES] = '/cases/pin'; API_URLS[ApiKeys.PINNED_CASES_V2] = '/cases/v2/pin'; API_URLS[ApiKeys.LOGOUT] = '/auth/logout'; API_URLS[ApiKeys.FEEDBACK] = '/cases/feedback'; API_URLS[ApiKeys.FILTERS] = '/cases/filters'; API_URLS[ApiKeys.JANUS] = '/events/json'; API_URLS[ApiKeys.GENERATE_PAYMENT_LINK] = '/payments/send-payment-link'; API_URLS[ApiKeys.GENERATE_PAYMENT_LINK_V2] = '/payments/v2/send-payment-link'; API_URLS[ApiKeys.ADDRESSES_GEOLOCATION] = '/addresses-geolocations'; API_URLS[ApiKeys.NEW_ADDRESS] = '/addresses'; API_URLS[ApiKeys.GET_SIGNED_URL] = '/cases/get-signed-urls'; API_URLS[ApiKeys.GET_SIGNED_URL_V2] = '/cases/v2/get-signed-urls'; API_URLS[ApiKeys.GET_SIGNED_URL_FOR_REPORTEE] = '/cases/get-signed-urls-for-reportee'; API_URLS[ApiKeys.GET_SIGNED_URL_FOR_REPORTEE_V2] = '/cases/v2/get-signed-urls-for-reportee'; API_URLS[ApiKeys.CASE_UNIFIED_DETAILS] = '/v3/collection-cases/unified-details/{loanAccountNumber}'; API_URLS[ApiKeys.CASE_UNIFIED_DETAILS_V4] = '/v5/collection-cases/unified-details/{loanAccountNumber}'; API_URLS[ApiKeys.UNGROUPED_ADDRESSES] = '/addresses/ungrouped-v2/{loanAccountNumber}'; API_URLS[ApiKeys.PAST_FEEDBACK] = '/feedback/filters'; API_URLS[ApiKeys.PAST_FEEDBACK_ON_ADDRESSES] = '/feedback/v2'; API_URLS[ApiKeys.NOTIFICATIONS] = '/notification/fetch'; API_URLS[ApiKeys.NOTIFICATION_ACTION] = '/notification/action'; API_URLS[ApiKeys.NOTIFICATION_DELIVERED] = '/notification/delivered'; API_URLS[ApiKeys.SEND_LOCATION] = '/geolocations/agents'; API_URLS[ApiKeys.VERIFY_GOOGLE_SIGN_IN] = '/auth/session/internal/exchange/v2'; API_URLS[ApiKeys.SYNC_TIME] = '/sync/server-timestamp'; API_URLS[ApiKeys.IS_DATA_SYNC_REQUIRED] = '/sync-data/is-sync-required'; API_URLS[ApiKeys.GET_PRE_SIGNED_URL_DATA_SYNC] = '/sync-data/get-pre-signed-url'; API_URLS[ApiKeys.DATA_SYNC_UPLOAD_COMPLETED] = '/sync-data/upload-completed'; API_URLS[ApiKeys.IMPERSONATION] = '/auth/impersonation'; API_URLS[ApiKeys.TELEPHONES] = '/telephones'; API_URLS[ApiKeys.CASES_SYNC_STATUS] = '/cases/agents/sync-status'; API_URLS[ApiKeys.CASES_SEND_ID] = '/cases/sync'; API_URLS[ApiKeys.FETCH_CASES] = '/cases/agents/{agentReferenceId}'; API_URLS[ApiKeys.GET_FORECLOSURE_AMOUNT] = '/{loanAccountNumber}/pre-closure-amount/v2'; API_URLS[ApiKeys.UPLOAD_FEEDBACK_IMAGES] = '/feedback/persist-original-images'; API_URLS[ApiKeys.GLOBAL_CONFIG] = '/global-config'; API_URLS[ApiKeys.UPLOAD_IMAGE_ID] = '/user/documents/selfie'; API_URLS[ApiKeys.GET_DOCUMENTS] = '/user/documents'; API_URLS[ApiKeys.REPORTEES] = '/user/all-field-reportees'; API_URLS[ApiKeys.GET_AGENT_DETAIL] = '/user/role-info'; API_URLS[ApiKeys.GET_PERFORMANCE_METRICS] = '/allocation-cycle/agent-performance'; API_URLS[ApiKeys.GET_CASH_COLLECTED] = '/allocation-cycle/cash-collected-split'; API_URLS[ApiKeys.GET_TELEPHONE_NUMBERS] = '/v2/collection-cases/telephones-view/{loanAccountNumber}'; API_URLS[ApiKeys.GET_TELEPHONE_NUMBERS_V2] = '/collections/telephones-agent-call-activity-view'; API_URLS[ApiKeys.FIRESTORE_INCONSISTENCY_INFO] = '/cases/sync-status'; API_URLS[ApiKeys.FIRESTORE_INCONSISTENCY_INFO_V2] = '/cases/v2/sync-status'; API_URLS[ApiKeys.GET_CASE_DETAILS_FROM_API] = '/collection-cases/minimal-collection-case-view/{caseId}'; API_URLS[ApiKeys.GET_CASE_DETAILS_FROM_API_V2] = '/v2/collection-cases/minimal-collection-case-view/{caseId}'; API_URLS[ApiKeys.DAILY_COMMITMENT] = '/daily-commitment'; API_URLS[ApiKeys.GET_PTP_AMOUNT] = '/ptps-due-view/agent-detail'; API_URLS[ApiKeys.GET_VISIBILITY_STATUS] = '/daily-commitment/visibility'; API_URLS[ApiKeys.SIMILAR_GEOLOCATION_TIMESTAMPS] = '/v1/geolocation-cluster/{clusterId}/similar-locations-info'; API_URLS[ ApiKeys.GET_PRE_SIGNED_URL ] = `/agent-data-sync/presigned-url?userReferenceId={agentID}&deviceReferenceId={deviceID}&dataSyncType={dataSyncType}`; API_URLS[ApiKeys.SEND_UPLOAD_ACK] = '/agent-data-sync/{requestId}'; API_URLS[ApiKeys.GET_CSA_TICKETS] = '/support-requests/fetch-all'; API_URLS[ApiKeys.GET_CSA_SINGLE_TICKET] = '/support-requests/{ticketReferenceId}'; API_URLS[ApiKeys.CREATE_TICKET] = '/support-requests'; API_URLS[ApiKeys.ACKNOWLEDGE_TICKET] = '/support-requests/{ticketReferenceId}/acknowledge?supportRequestUserType=FE'; API_URLS[ApiKeys.ADD_COMMENT] = '/support-requests/{ticketReferenceId}/comments'; API_URLS[ApiKeys.UPDATE_TICKET_STATUS] = '/support-requests/{ticketReferenceId}'; API_URLS[ApiKeys.GET_CSA_FILTERS] = '/support-requests/filters'; API_URLS[ApiKeys.GET_FORM_OPTIONS] = '/support-requests/form'; API_URLS[ApiKeys.GET_UPDATE_COUNT] = '/support-requests/summary'; API_URLS[ApiKeys.DUE_AMOUNT_SUMMARY] = '/collection-cases/{loanAccountNumber}/amount-summary'; API_URLS[ApiKeys.FEE_WAIVER_HISTORY] = '/collection-cases/{loanAccountNumber}/waiver-history'; API_URLS[ApiKeys.FEE_WAIVER_V2] = '/loan/request/{loanAccountNumber}/adjust-component/v2'; API_URLS[ApiKeys.GET_PIN_CODES_DETAILS] = '/api/v1/pincodes/{pinCode}'; API_URLS[ApiKeys.SYNC_COSMOS_TO_LONGHORN] = '/sync/tele-cosmos-sync'; API_URLS[ApiKeys.CALL_CUSTOMER] = '/call-recording/v2/call-request'; API_URLS[ApiKeys.SYNC_ACTIVE_CALL_DETAILS] = '/call-recording/call-status'; API_URLS[ApiKeys.GET_CALL_HISTORY] = '/call-recording/v3/call-history'; API_URLS[ApiKeys.SYNC_CALL_FEEDBACK_NUDGE_DETAILS] = '/call-recording/acknowledge-feedback-nudge/{callId}'; API_URLS[ApiKeys.FETCH_CUSTOMER_DOCUMENTS] = '/documents/{loanAccountNumber}'; API_URLS[ApiKeys.FETCH_AGENT_DOCUMENTS] = '/documents/agent'; API_URLS[ApiKeys.FETCH_DOCUMENT_SPECIFIC_LANGUAGE] = '/documents/language/{loanAccountNumber}'; API_URLS[ApiKeys.SEND_COMMUNICATION_NAVI_ACCOUNT] = '/navi-communications/{loanAccountNumber}'; API_URLS[ApiKeys.GENERATE_DYNAMIC_DOCUMENT] = '/documents/generate/{loanAccountNumber}'; API_URLS[ApiKeys.DOWNLOAD_LATEST_APP] = 'https://longhorn.navi.com/api/app/download'; API_URLS[ApiKeys.ALL_ESCALATIONS] = '/customer-escalation'; API_URLS[ApiKeys.GET_UNGROUPED_ADDRESSES] = '/collection-cases/ungrouped/addresses'; API_URLS[ApiKeys.GET_GROUPED_ADDRESSES_AND_GEOLOCATIONS] = '/collection-cases/grouped/addresses-geo-locations'; API_URLS[ApiKeys.GET_EMI_SCHEDULE] = '/collection-cases/emiSchedule'; API_URLS[ApiKeys.GET_REPAYMENTS] = '/collection-cases/repayments'; API_URLS[ApiKeys.GET_FEEDBACK_HISTORY] = '/feedback/filters'; API_URLS[ApiKeys.GET_PRIORTIY_FEEDBACK] = '/feedback/case-status'; API_URLS[ApiKeys.GET_TRAINING_MATERIAL_LIST] = '/training-page/content-list'; API_URLS[ApiKeys.GET_TRAINING_MATERIAL_DETAILS] = '/training-page/{docRefId}'; API_URLS[ApiKeys.SELF_CALL_ACK] = '/sync-data/self-call-metadata'; export const API_STATUS_CODE = { OK: 200, CREATED: 201, BAD_REQUEST: 400, UNAUTHORIZED: 401, FORBIDDEN: 403, NOT_FOUND: 404, UNPROCESSABLE_CONTENT: 422, INTERNAL_SERVER_ERROR: 500, TOO_MANY_REQUESTS: 429, GONE: 410, POST_OPERATIVE_HOURS_ACTIVITY: 451, }; export const UNAUTHORIZED_VALUES = [API_STATUS_CODE.UNAUTHORIZED, API_STATUS_CODE.FORBIDDEN]; const API_TIMEOUT_INTERVAL = 2e4; // 20s let dispatch: Dispatch; export const getErrorMessage = (err: any) => { if (err?.response?.data?.title) { return err?.response?.data?.title; } const errorContent = err?.response?.data?.message ? JSON.parse(err?.response?.data?.message) : ''; return errorContent?.detail || errorContent?.message || errorContent || err; }; export function getApiUrl( apiKey: ApiKeys, params?: Record, queryParams?: Record ) { let apiUrl = API_URLS[apiKey]; // replace all {placeholders} with their values in params if (params) { Object.keys(params).forEach((paramKey) => { apiUrl = apiUrl.split(`{${paramKey}}`).join(`${params[paramKey]}`); // apiUrl = apiUrl.replaceAll(`{${paramKey}}`, `${params[paramKey]}`); }); } if (queryParams) { apiUrl += '?' + _map(queryParams, (key) => `${key}=${queryParams[key]}`).join('&'); } return `${apiUrl}`; } // status code to be retried on const errorsToRetry = [500, 503]; const axiosInstance = axios.create({ timeout: API_TIMEOUT_INTERVAL }); axiosInstance.interceptors.request.use((request) => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore request.headers['X-Auth-Source'] = 'mjolnir'; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore request.retry = request?.retry < 4 ? request.retry : 3; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore request.delay = request?.delay > 2000 ? request.delay : 2000; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore request.headers['request-start-time'] = Date.now(); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore request.headers['X-Session-Token'] = GLOBAL.SESSION_TOKEN || ''; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore request.headers['X-Device-Id'] = GLOBAL.DEVICE_ID || ''; const abortController = new AbortController(); if (GLOBAL.IS_IMPERSONATED) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore request.headers['X-Impersonation-Session-Id'] = GLOBAL.SESSION_TOKEN || ''; const requestType = request?.method ?? ''; if (REQUEST_TYPE_TO_BLOCK_FOR_IMPERSONATION.includes(requestType)) { const url = request?.url ?? ''; let isUrlUnBlocked = false; REQUEST_TO_UNBLOCK_FOR_IMPERSONATION.forEach((requestPattern) => { if (compareUrl(url, requestPattern)) { isUrlUnBlocked = true; } }); if (!isUrlUnBlocked) { request.headers['donotHandleError'] = true; abortController.abort(); } } } return { ...request, signal: abortController.signal, }; }); axiosInstance.interceptors.response.use( (response) => { if (response.config.headers) { const start = response.config.headers['request-start-time']; const end = Date.now(); const milliseconds = end - Number(start); response.headers['request-duration'] = String(milliseconds); sendApiToClickstreamEvent(response, milliseconds, true); } return response; }, (error) => { if (axios.isCancel(error) && GLOBAL.IS_IMPERSONATED) { toast({ type: 'error', text1: ToastMessages.NOT_ALLOWED_ERROR, }); } const { config, response } = error; if (response?.status === 400) { alfredHandleSWWEvent(new Error('API Error occured')); } logError(error as Error, config?.baseURL + config?.url); const start = response?.config?.headers['request-start-time']; const end = Date.now(); const milliseconds = end - Number(start); sendApiToClickstreamEvent(response, milliseconds, false); addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_API_FAILED, { statusCode: response?.status, url: response?.config?.url, }); const donotHandleErrorOnStatusCode = (config.headers.donotHandleErrorOnStatusCode || []).map( Number ); if ( (config?.headers?.donotHandleError || donotHandleErrorOnStatusCode.includes(error?.response?.status)) && // Logout even donotHandleError is true when status code is 401, 403 !config?.headers?.autoLogoutOnUnauthorized ) { return Promise.reject(error); } if (!config || config.retry <= 1 || !errorsToRetry.includes(error?.response?.status)) { const errorString = getErrorMessage(error); if ( !config.headers.donotHandleError && (config.headers?.showInSpecificComponents ? config.headers.showInSpecificComponents?.includes(getCurrentScreen()?.name) : true) ) { if (API_STATUS_CODE.GONE !== response?.status) { toast({ type: 'error', text1: typeof errorString === 'string' ? errorString : API_ERROR_MESSAGE, }); } } if ([API_STATUS_CODE.UNAUTHORIZED, API_STATUS_CODE.FORBIDDEN].includes(response?.status)) { // Reset user info dispatch(handleLogout()); } // Blocking cosmos after operative hours if (API_STATUS_CODE.GONE === response?.status && !GLOBAL.IS_IMPERSONATED) { if (store?.getState().user.withinOperativeHours) { dispatch(setWithinOperativeHours(false)); } } return Promise.reject(error); } config.retry -= 1; const delayRetryRequest = new Promise((resolve) => { setTimeout(() => { resolve(); }, config.delay); }); config.delay *= 2; return delayRetryRequest.then(() => axiosInstance(config)); } ); axiosInstance.defaults.headers.common['Content-Type'] = 'application/json'; axiosInstance.defaults.baseURL = BASE_AV_APP_URL; // TODO:: Ideally should happen through middlewares. export const registerNavigateAndDispatch = (dispatchParam: Dispatch) => (dispatch = dispatchParam); export const isAxiosError = (err: Error) => { return axios.isAxiosError(err); }; export default axiosInstance;