Skip to content

Instantly share code, notes, and snippets.

@sbrl
Created February 13, 2020 16:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sbrl/7a79eedf000929e09e3e222714c2f53a to your computer and use it in GitHub Desktop.
Save sbrl/7a79eedf000929e09e3e222714c2f53a to your computer and use it in GitHub Desktop.
[Retry.mjs] Retry a function automatically a specified number of times #utility
"use strict";
import l from './Log.mjs';
import { ErrorWrapper } from './Errors.mjs';
/**
* Tries to execute a given function, and retried it a specified number of
* times if it throws an error.
* @param {Number} times The number of times to retry before giving up and throwing an error ourselves.
* @param {Function} func The function to execute.
* @param {Array} args The arguments to pass to the function that will be executed.
* @return {any} The return value of the executed function if it was successful (if it isn't successful even after retries, an error is thrown).
*/
function retry(times, func, ...args) {
let return_result = null, last_error = null, success = false;
for(let i = 0; i < times; i++) {
success = false;
try {
return_result = func(...args);
success = true;
}
catch(error) {
l.warn(`Warning: Encountered error runnign retry function:`, error);
last_error = error;
success = false;
}
if(success)
break;
}
if(!success) {
throw new ErrorWrapper(`Error: Failed to execute function after retrying ${times} times.`, last_error);
}
return return_result;
}
/**
* Tries to execute a given function, and retried it a specified number of
* times if it throws an error.
* Async version.
* @param {Number} times The number of times to retry before giving up and throwing an error ourselves.
* @param {Function} func The function to execute.
* @param {Array} args The arguments to pass to the function that will be executed.
* @return {Promise<any>} The return value of the executed function if it was successful (if it isn't successful even after retries, an error is thrown).
*/
async function retry_async(times, func, ...args) {
let return_result = null, last_error = null, success = false;
for(let i = 0; i < times; i++) {
success = false;
try {
return_result = await func(...args);
success = true;
}
catch(error) {
l.warn(`Warning: Encountered error runnign retry function:`, error);
last_error = error;
success = false;
}
if(success)
break;
}
if(!success) {
throw new ErrorWrapper(`Error: Failed to execute function after retrying ${times} times.`, last_error);
}
return return_result;
}
export { retry, retry_async };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment