import axios, { AxiosError } from 'axios'; import { initAjaxHandlersCommon } from './ajax-handlers-common'; import { initAjaxHandlersUnauthorized, UnauthorizedHandler } from './ajax-handlers-unauthorized'; import { INotifier, Status } from './common'; import { loader } from './loader'; export const initAjaxHandlers = ({ notifier, errorFilteredUrls = [], unauthorizedHandler, }: { notifier?: INotifier; errorFilteredUrls?: string[]; unauthorizedHandler?: true | UnauthorizedHandler; } = {}) => { initAjaxHandlersCommon(); if (unauthorizedHandler) { initAjaxHandlersUnauthorized( unauthorizedHandler === true ? undefined : unauthorizedHandler ); } const logError = ({ request, config }: AxiosError) => { notifier?.log?.({ exception: request.message, category: 'NetworkConnection', message: 'Network Connection Error', data: { status: request.status, requestUrl: config?.url, readyState: request.readyState, }, }); }; const showError = (error: any) => { const isHardError = !!error.response?.headers?.harderror; const message = (error.response?.data?.Error?.Message ?? error.response?.headers?.['x-message'] ?? error.response?.statusText) || // eslint-disable-line @typescript-eslint/prefer-nullish-coalescing (typeof error === 'string' ? error : 'Error'); const isConnectionError = !error.response?.status; if (isHardError) { const isReportable = error.response?.headers?.isreportable?.trim() === 'true'; notifier?.show?.({ status: Status.Error, title: 'Application error', duration: 0, action: { label: 'Show details', onClick: () => { window.dispatchEvent( new CustomEvent('report_error', { detail: { errorLogEntryId: error.response?.headers?.errorlogentryid.trim(), message, }, }) ); }, }, detail: { isHardError, isReportable, baseUrl: error.config.baseURL, url: error.config.url, }, }); } else { notifier?.show?.({ status: Status.Warning, title: 'Action cancelled', message: isConnectionError ? `${message}\r\n` + `URL: ${error.config.url}\r\n` + `Status Code: ${ error.response ? error.response.status : error.request ? error.request.status : 0 }` : message, detail: { isConnectionError, isHardError, baseUrl: error.config.baseURL, url: error.config.url, }, }); } }; axios.interceptors.request.use( config => { if (!config.hideGlobalLoader) { loader.show(); } return config; }, (error: AxiosError) => { if (!error.config?.hideGlobalLoader) { loader.hide(); } if (error.request?.status === 0) { logError(error); } return Promise.reject(error); } ); axios.interceptors.response.use( response => { if (!response.config.hideGlobalLoader) { loader.hide(); } return response; }, error => { if (!error.config?.hideGlobalLoader) { loader.hide(); } if (error.request?.status === 0) { logError(error); } // fail silently if request was cancelled, and return a never resolving promise if (axios.isCancel(error)) { return new Promise(() => {}); } if ( !error.config?.suppressShowError || (Array.isArray(error.config?.suppressShowError) && !error.config?.suppressShowError.includes(error.response?.status)) || (typeof error.config?.suppressShowError === 'function' && !error.config.suppressShowError(error)) ) { const isFiltered = errorFilteredUrls.some(url => error.config?.url?.startsWith(url) ); const isCodedException = !!error.response?.data?.Error?.Code; const isAborted = typeof error === 'string' && error === 'abort'; if (!isFiltered && !isCodedException && !isAborted) { showError(error); } } return Promise.reject(error); } ); };