UNPKG

@widergy/web-utils

Version:
206 lines (205 loc) 10.7 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildApi = exports.addNoCacheHeader = exports.createApiMonitors = exports.API_MONITORS = void 0; const defaultMessages_1 = require("./constants/defaultMessages"); const errorCodes_1 = __importDefault(require("./constants/errorCodes")); const errorHandling_1 = require("./errorHandling"); exports.API_MONITORS = { SESSION_EXPIRED: 'sessionExpired', MISSING_PARAMETER: 'missingParameter', INVALID_PARAMETERS: 'invalidParameters', USER_ERROR: 'userError', RECORD_NOT_UNIQUE: 'recordNotUnique', SERVER_ERROR: 'serverError', ERROR_USER_UPDATE: 'errorUserUpdate', ROUTING_ERROR: 'routingError', OUTDATED_TOKEN: 'outdatedToken', CLIENT_ERROR: 'clientError', CIRCUIT_OPEN: 'circuitOpen', TIMEOUT_CLIENT: 'timeoutClient' }; const getMonitorParams = (response, options) => { const extraParams = options.getMonitorParams ? options.getMonitorParams() : {}; return Object.assign({ originalURL: (response.originalUrl || (response.config && response.config.url)).replace('https://', ''), data: response.data, requestHeaders: response.config && response.config.headers, responseHeaders: response.headers, timeout: response.config && response.config.timeout }, extraParams); }; const sessionExpirationMonitor = (rollbarTracker, response = {}, options = {}) => { if (response.status === 401 && (0, errorHandling_1.existsErrorCodes)([errorCodes_1.default.NOT_AUTHORIZED, errorCodes_1.default.AUTH_TOKEN_EXPIRED, errorCodes_1.default.USER_NOT_AUTHENTICATED], response.data)) { const parameters = getMonitorParams(response, options); if (!options.ignoreRollbar) rollbarTracker.info('Session expired', parameters); options.callback && options.callback(); } }; const missingParametersMonitor = (rollbarTracker, response = {}, options = {}) => { if ((0, errorHandling_1.existsErrorCode)(errorCodes_1.default.PARAM_IS_MISSING, response.data)) { const parameters = getMonitorParams(response, options); if (!options.ignoreRollbar) rollbarTracker.error(`Missing parameter at: ${parameters.originalURL}`, parameters); options.callback && options.callback(); } }; const invalidParametersMonitor = (rollbarTracker, response = {}, options = {}) => { if ((0, errorHandling_1.existsErrorCodes)([errorCodes_1.default.INVALID_PARAM, errorCodes_1.default.INVALID_PARAMS], response.data)) { const parameters = getMonitorParams(response, options); if (!options.ignoreRollbar) rollbarTracker.error(`Invalid parameters at: ${parameters.originalURL}`, parameters); options.callback && options.callback(); } }; const userErrorMonitor = (rollbarTracker, response = {}, options = {}) => { const parameters = getMonitorParams(response, options); if ((0, errorHandling_1.existsErrorCode)(errorCodes_1.default.USER_ERROR, response.data) && parameters.originalURL.includes('users/client_auth')) { rollbarTracker.error('Error on federated user login', parameters); options.callback && options.callback(); } }; const recordNotUniqueMonitor = (rollbarTracker, response = {}, options = {}) => { if ((0, errorHandling_1.existsErrorCode)(errorCodes_1.default.RECORD_NOT_UNIQUE, response.data)) { const parameters = getMonitorParams(response, options); rollbarTracker.error(`Record not unique at: ${parameters.originalURL}`, parameters); options.callback && options.callback(); } }; const serviceUnavailableMonitor = (rollbarTracker, response = {}, options = {}) => { if (response.status === 503 && (0, errorHandling_1.existsErrorCode)(errorCodes_1.default.SERVER_ERROR, response.data)) { const parameters = getMonitorParams(response, options); rollbarTracker.error(`Server error at: ${parameters.originalURL}.`, parameters); options.callback && options.callback(); } }; const userUpdateErrorMonitor = (rollbarTracker, response = {}, options = {}) => { if (response.status === 500 && response.data && response.data.errors && response.data.errors[0] && response.data.errors[0].meta.includes('undefined method')) { const parameters = getMonitorParams(response, options); if (!options.ignoreRollbar) rollbarTracker.error(`Error on user update at: ${parameters.originalURL}`, parameters); options.callback && options.callback(); } }; const routingErrorMonitor = (rollbarTracker, response = {}, options = {}) => { if ((0, errorHandling_1.existsErrorCode)(errorCodes_1.default.ROUTING_ERROR, response.data)) { const parameters = getMonitorParams(response, options); if (!options.ignoreRollbar) rollbarTracker.info(`Routing error at: ${parameters.originalURL}`, parameters); options.callback && options.callback(); } }; const outdatedTokenMonitor = (rollbarTracker, response = {}, options = {}) => { if (response.status === 401 && (0, errorHandling_1.existsErrorCodes)([errorCodes_1.default.OUTDATED_TOKEN], response.data)) { const parameters = getMonitorParams(response, options); if (!options.ignoreRollbar) rollbarTracker.info('Entered from another device', parameters); options.callback && options.callback(response.data); } }; const clientErrorMonitor = (_, response = {}, options = {}) => { const clientErrorCodes = [errorCodes_1.default.UTILITY_ERROR, errorCodes_1.default.EXTERNAL_API_ERROR]; if (response.status >= 500 && (0, errorHandling_1.existsErrorCodes)(clientErrorCodes, response.data)) { options.callback && options.callback(response.data); } }; const circuitOpenMonitor = (_, response = {}, options = {}) => { const circuitOpenCodes = [errorCodes_1.default.CIRCUIT_OPEN_ERROR]; if (response.status === 503 && (0, errorHandling_1.existsErrorCodes)(circuitOpenCodes, response.data)) { options.callback && options.callback(response.data); } }; const timeoutClientMonitor = (_, response = {}, options = {}) => { const timeoutClientCodes = [errorCodes_1.default.GATEWAY_TIMEOUT]; if (response.status === 504 && (0, errorHandling_1.existsErrorCodes)(timeoutClientCodes, response.data)) { options.callback && options.callback(response.data); } }; const monitors = [ { key: exports.API_MONITORS.SESSION_EXPIRED, func: sessionExpirationMonitor }, { key: exports.API_MONITORS.MISSING_PARAMETER, func: missingParametersMonitor }, { key: exports.API_MONITORS.INVALID_PARAMETERS, func: invalidParametersMonitor }, { key: exports.API_MONITORS.USER_ERROR, func: userErrorMonitor }, { key: exports.API_MONITORS.RECORD_NOT_UNIQUE, func: recordNotUniqueMonitor }, { key: exports.API_MONITORS.SERVER_ERROR, func: serviceUnavailableMonitor }, { key: exports.API_MONITORS.ERROR_USER_UPDATE, func: userUpdateErrorMonitor }, { key: exports.API_MONITORS.ROUTING_ERROR, func: routingErrorMonitor }, { key: exports.API_MONITORS.OUTDATED_TOKEN, func: outdatedTokenMonitor }, { key: exports.API_MONITORS.CLIENT_ERROR, func: clientErrorMonitor }, { key: exports.API_MONITORS.CIRCUIT_OPEN, func: circuitOpenMonitor }, { key: exports.API_MONITORS.TIMEOUT_CLIENT, func: timeoutClientMonitor }, ]; const createApiMonitors = (apiInstance, rollbarTracker, options = {}, disableMonitors = []) => { if (!apiInstance || !rollbarTracker) return console.warn(apiInstance ? defaultMessages_1.DefaultMessages.rollbarInstanceError : defaultMessages_1.DefaultMessages.apiInstanceError); monitors.forEach((monitor) => !disableMonitors.includes(monitor.key) && apiInstance.addMonitor((response) => monitor.func(rollbarTracker, response, options[monitor.key]))); }; exports.createApiMonitors = createApiMonitors; const addNoCacheHeader = (config = {}) => (Object.assign(Object.assign({}, config), { headers: Object.assign(Object.assign({}, (config.headers ? config.headers : {})), { 'Cache-Control': 'no-cache' }) })); exports.addNoCacheHeader = addNoCacheHeader; const API_UTILS = { addNoCacheHeader: exports.addNoCacheHeader, createApiMonitors: exports.createApiMonitors, API_MONITORS: exports.API_MONITORS, }; const createCancelablePromise = (promise, controller) => { return new Promise((resolve, reject) => { promise .then(response => { if (!controller.signal.aborted) { resolve(response); } }) .catch(error => { reject(error); }); controller.signal.addEventListener('abort', () => { reject(new Error('Promise was canceled')); }); }); }; const requestTimeout = (promise, axiosConfig, reqConfig) => { const config = Object.assign(Object.assign({}, axiosConfig), (reqConfig || {})); const duration = parseInt(config.timeout, 10); const promiseController = new AbortController(); const timeoutPromise = new Promise(resolve => { setTimeout(() => { resolve({ ok: false, problem: 'TIMEOUT_ERROR', originalError: 'REQUEST_TIMEOUT_ERROR', data: null, status: null, headers: null, config, duration, }); }, duration); }); const cancelablePromise = createCancelablePromise(promise, promiseController); return Promise.race([timeoutPromise, cancelablePromise]) .then(response => { promiseController.abort(); return response; }) .catch(error => error); }; const buildApi = (config, create) => { const api = create(config); const { axiosInstance: { defaults }, get, delete: del, head, post, put, patch, link, unlink, } = api; api.get = (...args) => requestTimeout(get(...args), defaults, args[2]); api.delete = (...args) => requestTimeout(del(...args), defaults, args[2]); api.head = (...args) => requestTimeout(head(...args), defaults, args[2]); api.post = (...args) => requestTimeout(post(...args), defaults, args[2]); api.put = (...args) => requestTimeout(put(...args), defaults, args[2]); api.patch = (...args) => requestTimeout(patch(...args), defaults, args[2]); api.link = (...args) => requestTimeout(link(...args), defaults, args[2]); api.unlink = (...args) => requestTimeout(unlink(...args), defaults, args[2]); return api; }; exports.buildApi = buildApi; exports.default = API_UTILS;