import axios from 'axios'; import analyticsMixIn from '@/mixins/analytics-mixin.js'; import { useMainStore } from '@/store'; import applicationConfig from '@/constants/application-config.js'; import { GaCategories, GaActions, GaLabels } from '@/constants/analytics'; import headerKeys from '@/constants/header-keys'; import axiosResponseInterceptorMessages from '@/constants/axios-response-interceptor-messages.js'; import { getSessionKeyValue } from '@/helpers/cookie-helper'; import endpoints from "@/constants/endpoints"; import queryStrings from '@/constants/query-strings'; import issPageValues from '@/router/router-constants/issPage-values'; // Add a response interceptor for global axios error handing. axios.interceptors.response.use( (response) => response, (error) => { let rejectionError = ''; if (typeof error.response === 'undefined') { // The request was not made, could be a bad url, bad connection or a CORS error. rejectionError = { cause: error, response: error, message: axiosResponseInterceptorMessages.NETWORK_ERROR }; } else if (error.response) { // The request was made and the server responded with a status code // that falls out of the range of 2xx rejectionError = { response: error.response, message: axiosResponseInterceptorMessages.STATUS_CODE_ERROR }; } else if (error.request) { // The request was made but no response was received // `error.request` is an instance of XMLHttpRequest in the browser and an instance of // http.ClientRequest in node.js rejectionError = { response: error.request, message: axiosResponseInterceptorMessages.NO_RESPONSE_ERROR }; } else { // Something happened in setting up the request that triggered an Error rejectionError = { response: error.message, message: axiosResponseInterceptorMessages.GENERIC_ERROR }; } return Promise.reject(rejectionError); } ); export default { getPageNameByQueryString() { const params = new URLSearchParams(location.search); if (params.has(queryStrings.ISS_PAGE)) { return params.get(queryStrings.ISS_PAGE); } return ''; }, callHttpClient({ method, endpoint, payload, logApiCall = true, bailoutOnError = true }) { return new Promise((resolve, reject) => { const store = useMainStore(); const currentPageName = this.getPageNameByQueryString().toLowerCase(); const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO; const payloadAndAnalyticsData = { ...payload, AppName: 'ISS' }; const sessionKey = getSessionKeyValue(); const headers = { [headerKeys.EXPERIMENT]: JSON.stringify(store.experimentSettings), [headerKeys.APPLICATION_NAME]: applicationConfig.APPLICATION_NAME, [headerKeys.TRANSACTION_ID]: crypto.randomUUID(), [headerKeys.ENTERPRISE_ORDER_NUMBER]: store.order.eon, [headerKeys.REFERRAL_SEQUENCE_NUMBER]: store.order.referralSequenceNumber, [headerKeys.SESSION_SEQUENCE_NUMBER]: sessionKey }; const url = cfDistroUrl + endpoint; axios({ method, url, data: payloadAndAnalyticsData, crossDomain: true, responseType: 'json', headers }) .then( (response) => { if (logApiCall) { analyticsMixIn.methods.pushEventToGA( GaCategories.API_RESPONSE, GaActions.RESULT, `${GaLabels.SUCCESS}_${endpoint}`, true ); } return resolve(response); }, (error) => { // Add any logging specific endpoints here. if ( endpoint.toLowerCase().includes(endpoints.LogIssSessionData.url) || endpoint.toLowerCase().includes(endpoints.LogPageView.url) || endpoint.toLowerCase().includes(endpoints.LogCustomEvent.url) ) { return resolve({ data: null, error: "Ignore errors when logging" }); } else { if (logApiCall) { analyticsMixIn.methods.pushEventToGA( GaCategories.API_RESPONSE, GaActions.RESULT, `${GaLabels.ERROR}_${endpoint}`, true ); } if (error.response.status !== 404) { const errorData = { method, url, payload, error }; global.$logger.logError(`${method}: ${endpoint}`, errorData); if (bailoutOnError && global.bailoutOnAxiosError !== undefined ) { // Check for bailout or entry page here ... if we are on these pages we cannot bailout. if ( currentPageName != issPageValues.ENTRY_PAGE && currentPageName != issPageValues.BAILOUT_PAGE) { global.bailoutOnAxiosError(errorData); } else { console.error("Fatal - Unable to bailout on the entry page or bailout page."); // Redirect to a generic static error page on fatal error on entry and bailout page. window.top.location = '/static/error/index.html'; } } } return reject(error.response); } } ); }); }, // used for mocked services async mockCallHttpClient(method, endpoint) { return new Promise((resolve, reject) => { axios({ method, url: endpoint, crossDomain: true, responseType: {} }) .then( (response) => resolve(response), (error) => { window.console.error(error); return reject(error.response); } ); }); } };