Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
GASRetry - Exponential backoff JavaScript implementation for Google Apps Script (Library project key: "MGJu3PS2ZYnANtJ9kyn2vnlLDhaBgl_dE")
/**
* Invokes a function, performing up to 5 retries with exponential backoff.
* Retries with delays of approximately 1, 2, 4, 8 then 16 seconds for a total of
* about 32 seconds before it gives up and rethrows the last error.
* See: https://developers.google.com/google-apps/documents-list/#implementing_exponential_backoff
* <br>Author: peter.herrmann@gmail.com (Peter Herrmann)
<h3>Examples:</h3>
<pre>//Calls an anonymous function that concatenates a greeting with the current Apps user's email
var example1 = GASRetry.call(function(){return "Hello, " + Session.getActiveUser().getEmail();});
</pre><pre>//Calls an existing function
var example2 = GASRetry.call(myFunction);
</pre><pre>//Calls an anonymous function that calls an existing function with an argument
var example3 = GASRetry.call(function(){myFunction("something")});
</pre><pre>//Calls an anonymous function that invokes DocsList.setTrashed on myFile and logs retries with the Logger.log function.
var example4 = GASRetry.call(function(){myFile.setTrashed(true)}, Logger.log);
</pre>
*
* @param {Function} func The anonymous or named function to call.
* @param {Function} optLoggerFunction Optionally, you can pass a function that will be used to log
to in the case of a retry. For example, Logger.log (no parentheses) will work.
* @return {*} The value returned by the called function.
*/
function call_(func, optLoggerFunction) {
for (var n=0; n<6; n++) {
try {
return func();
} catch(e) {
if (optLoggerFunction) {optLoggerFunction("GASRetry " + n + ": " + e)}
if (n == 5) {
throw JSON.stringify(catchToObject_(e));
}
Utilities.sleep((Math.pow(2,n)*1000) + (Math.round(Math.random() * 1000)));
}
}
}
// For catching errors
function catchToObject_(error) {
var errInfo = {};
// file info
var ssIn = SpreadsheetApp.getActive();
if (ssIn) {
errInfo.fileName = ssIn.getName();
errInfo.fileUrl = ssIn.getUrl();
}
var scriptId = ScriptApp.getScriptId();
var scriptFile = DriveApp.getFileById(scriptId);
if (scriptFile) {
errInfo.scriptName = scriptFile.getName();
}
errInfo.scriptUrl = 'https://script.google.com/macros/d/' + scriptId + '/edit';
// error info
if (typeof error !== 'string') {
for (var prop in error) {
errInfo[prop] = error[prop];
}
}
errInfo.value = error.toString();
if (stack) {
errInfo.stack = stack.split('\n');
}
return errInfo;
}
function test_callWithError()
{
call_(test_withError_);
}
function test_withError_()
{
SpreadsheetApp.openById('Boooo');
}
/// measuring time elapsed
// usage
function test_functionTime() {
var t = new Date();
// YOUR CODE
Browser.msgBox('Done! The time to run function is ' + getTimeEllapse_(t));
}
function getTimeEllapse_(t)
{
var dif = new Date() - t;
if (dif < 1000) { return dif + ' ms.'; }
var mm = parseInt(dif/1000), respo = '';
if (mm < 60)
{
respo = mm + ' sec.';
}
else
{
var min = parseInt(mm / 60);
var sec = mm - min *60;
respo = min + ' min. ' + sec + ' sec.';
}
return respo;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment