@cooperwfloyd/fancyfetch
Version:
A simple, lightweight and isomorphic extension of the Fetch API that allows for graceful error handling and response validation, automatic retries, and the ability to bring your own Fetch API package.
31 lines (16 loc) • 3.58 kB
JavaScript
;Object.defineProperty(exports,"__esModule",{value:!0});const r=async(r,e,t)=>{let o={log:!0,maxAttempts:1,...t};if(o?.fetch&&"function"!=typeof o?.fetch)throw Error(`Error in fancyfetch: extras.fetch must be a valid function.
extras.fetch: ${String(o?.fetch)}`);let n=(o?.fetch,"function"==typeof o?.fetch)?o.fetch:"function"==typeof fetch?fetch:"undefined"!=typeof global&&"function"==typeof global?.fetch?global.fetch:"undefined"!=typeof window&&"function"==typeof window?.fetch?window.fetch:null;if("function"!=typeof n)throw Error(`Error in fancyfetch: fetchToUse must be a valid function.
fetchToUse: ${String(n)}`);if("string"!=typeof r&&"object"!=typeof r)throw Error(`Error in fancyfetch: A valid fetch resource was not provided
reference: https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters
resource: ${JSON.stringify(r,null,2)}`);if(e&&"object"!=typeof e)throw Error(`Error in fancyfetch: options must be a valid object.
options: ${JSON.stringify(e,null,2)}`);if(o?.maxAttempts&&("number"!=typeof o?.maxAttempts||!Number.isInteger(o.maxAttempts)||o.maxAttempts<1))throw Error(`Error in fancyfetch: extras.maxAttempts must be a positive integer.
extras.maxAttempts: ${o.maxAttempts}`);if(o?.retryDelay&&("number"!=typeof o?.retryDelay||!Number.isInteger(o.retryDelay)||o.retryDelay<1))throw Error(`Error in fancyfetch: extras.retryDelay must be a positive integer.
extras.retryDelay: ${String(o.retryDelay)}`);if(o?.validateResponse&&"function"!=typeof o?.validateResponse)throw Error(`Error in fancyfetch: extras.validateResponse must be a valid function.
extras.validateResponse: ${String(o?.validateResponse)}`);if(o?.onError&&"function"!=typeof o.onError)throw Error(`Error in fancyfetch: extras.onError must be a valid function.
extras.onError: ${String(o.onError)}`);if(o?.onRetrySuccess&&"function"!=typeof o.onRetrySuccess)throw Error(`Error in fancyfetch: extras.onRetrySuccess must be a valid function.
extras.onRetrySuccess: ${String(o.onRetrySuccess)}`);if(o?.onRetryError&&"function"!=typeof o.onRetryError)throw Error(`Error in fancyfetch: extras.onRetryError must be a valid function.
extras.onRetryError: ${String(o.onRetryError)}`);let s=async r=>{if("number"!=typeof r&&!Number.isInteger(r))throw Error(`Error in sleep: ms must be a positive integer.
ms: ${String(r)}`);return await new Promise(e=>setTimeout(e,r))},i=0,a=async()=>{if(++i>o.maxAttempts)return new Response;try{let t=await n(r,e),f=!o?.validateResponse||await o.validateResponse(t.clone());if(f)return i>1&&(o?.log&&console.log("fancyfetch fetch retry successful"),o?.onRetrySuccess&&o.onRetrySuccess()),t;if(1===o.maxAttempts)return new Response;return o?.log&&console.error(`Error in fancyfetch: Fetch was successful but didn't pass validateResponse. Retrying${o?.retryDelay!==void 0?` in ${String(o.retryDelay)} ms`:""}...`),o?.onRetryError&&o.onRetryError(),o?.retryDelay!==void 0&&await s(o?.retryDelay),await a()}catch(r){if(o?.log&&console.error("Error in fancyfetch",r),1===o.maxAttempts)return new Response;return o?.log&&console.error(`Error in fancyfetch: Failed to fetch. Retrying${o?.retryDelay!==void 0?` in ${o?.retryDelay} ms`:""}...`,r),o?.onRetryError&&o.onRetryError(r),o?.retryDelay!==void 0&&await s(o?.retryDelay),await a()}},f=await a(),c=`Error in fancyfetch: No successful responses were returned.
resource: ${JSON.stringify(r,null,2)}
options: ${JSON.stringify(e,null,2)}
extras: ${JSON.stringify(o,null,2)}`;if(null===f){if(o?.onError)o?.log&&console.error(c),o.onError();else throw Error(c)}return f};module.exports=r;