import { AxiosRequestConfig, AxiosResponse } from "axios"; import { apiRespBaseType } from "../../api/axiosInstance"; import { showErrorToastNotification, showWarnToastNotification, } from "../ToastNotification"; const maxRetries = 3; const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); // TODO: refreshAuth fn needs to be prop drilled (well, it's not really 'drilling', but still it's a single level) // because hooks (namely, useContext) can't be used outside functional components // so find a better way to pass refreshAuth type APIWrapperProps = { apiFn( data?: any, config?: AxiosRequestConfig ): Promise>; refreshAuth: () => Promise; data?: any; config?: AxiosRequestConfig; }; const APIWrapper = async ({ apiFn, refreshAuth, data, config, }: APIWrapperProps) => { for (let i = 1; i <= maxRetries + 1; i++) { const apiResp = await apiFn(data, config); if (apiResp === undefined) { showErrorToastNotification("Please try again after sometime"); } else if (apiResp.status === 200) { return apiResp; } else if (apiResp.status === 401) { showWarnToastNotification("Session expired, refreshing..."); if (!(await refreshAuth())) { showErrorToastNotification("Session invalid."); return; } } else { showErrorToastNotification(apiResp.data.message); } await sleep(i * i * 1000); } showErrorToastNotification("Please try again after sometime"); return; }; export default APIWrapper;