Created
August 1, 2020 00:00
-
-
Save jesusgoku/03b82af517fcc7d1c138e5ad34d7fac4 to your computer and use it in GitHub Desktop.
Wrapper for axios with timeout and retry
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Request { | |
constructor(baseURL, { timeout, ...options } = {}) { | |
this.timeout = timeout; | |
this.client = axios.create({ | |
baseURL, | |
...options, | |
}); | |
return new Proxy(this, { | |
get(target, property) { | |
if (["get", "post", "put", "patch", "delete"].includes(property)) { | |
return (url, options) => | |
target.request(url, { ...options, method: property }); | |
} | |
return Reflect.get(...arguments); | |
}, | |
}); | |
} | |
/** | |
* Make request | |
* | |
* @param {string} url - some options | |
* @param {Object} options - request options | |
* @param {number} options.retry - number of retries before rejected | |
* @param {number} options.retryDelay - ms delay for retry | |
* @param {number} options.retryDelayFactor - factor to increase delay in each retry | |
* | |
* @returns {Promise<axios.Response>} | |
*/ | |
request( | |
url, | |
{ | |
timeout, | |
retry = 0, | |
retryDelay = 100, | |
retryDelayFactor = 2, | |
...options | |
} = {} | |
) { | |
const source = axios.CancelToken.source(); | |
const promise = this.client({ | |
url, | |
cancelToken: source.token, | |
...options, | |
}).catch((err) => { | |
if (!retry) { | |
throw err; | |
} | |
return new Promise((resolve) => { | |
setTimeout(resolve, retryDelay); | |
}).then(() => | |
this.request(url, { | |
...options, | |
retryDelay: retryDelay * retryDelayFactor, | |
retry: retry - 1, | |
}) | |
); | |
}); | |
const cancel = () => { | |
source.cancel(); | |
}; | |
promise.cancel = cancel; | |
if (Number.isInteger(this.timeout) || Number.isInteger(timeout)) { | |
setTimeout(cancel, this.timeout || timeout); | |
} | |
return promise; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Retry promise before rejected | |
* | |
* @param {Function} fn - function return a promise | |
* @param {Object} [options] - options | |
* @param {number} [options.maxRetries=10] - max retries before rejected | |
* @param {number} [options.retriesDelay=100] - ms for delay before next retry | |
* @param {number} [options.retriesDelayFactor=1] - factor for increase next retries delay | |
* | |
* @returns {Promise} | |
*/ | |
export function retryPromise( | |
fn, | |
{ maxRetries = 10, retriesDelay = 100, retriesDelayFactor = 1 } = {} | |
) { | |
return fn().catch((err) => { | |
if (!maxRetries) { | |
throw err; | |
} | |
return new Promise((resolve) => { | |
setTimeout(resolve, retriesDelay); | |
}).then(() => retry(fn, maxRetries - 1, retriesDelay * retriesDelayFactor)); | |
}); | |
} | |
/** | |
* Retry promise before rejected | |
* | |
* @param {Function} fn - function return a promise | |
* @param {Object} [options] - options | |
* @param {number} [options.maxRetries=10] - max retries before rejected | |
* @param {number} [options.retriesDelay=100] - delay before next retry | |
* @param {number} [options.retriesDelayFactor=1] - factor for increase next retries delay | |
* | |
* @returns {Promise} | |
*/ | |
export async function retryAsync( | |
fn, | |
{ maxRetries = 10, retriesDelay = 100, retriesDelayFactor = 1 } = {} | |
) { | |
try { | |
return await fn(); | |
} catch (err) { | |
if (!maxRetries) { | |
throw err; | |
} | |
await new Promise((resolve) => setTimeout(resolve, retriesDelay)); | |
return retry(fn, maxRetries - 1, retriesDelay * retriesDelayFactor); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment