Skip to content

Commit

Permalink
moved to silent failure by default, return ErrorHandler_.CustomError …
Browse files Browse the repository at this point in the history
…object,

add options.throwOnFailure to expBackoff()
  • Loading branch information
JeanRemiDelteil committed Apr 20, 2018
1 parent df23f60 commit f0151ae
Showing 1 changed file with 43 additions and 18 deletions.
61 changes: 43 additions & 18 deletions src/ErrorHandler.gs.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@
* @param {Function} func - The anonymous or named function to call.
*
* @param {{}} [options] - options for exponential backoff
* @param {boolean} options.withSilentFailure - default to FALSE, If true, will return null on failure
* @param {boolean} options.throwOnFailure - default to FALSE, If true, throw the ErrorHandler_.CustomError on failure
* @param {boolean} options.doNotLogKnownErrors - default to FALSE, if true, will not log known errors to stackdriver
* @param {boolean} options.verbose - default to FALSE, if true, will log a warning on a successful call that failed at least once
* @param {number} options.retryNumber - default to 5, maximum number of retry on error
*
* @return {* | null} - The value returned by the called function, or null on failure if withSilentFailure == true
* @return {* | ErrorHandler_.CustomError} - The value returned by the called function, or ErrorHandler_.CustomError on failure if throwOnFailure == false
*/
function expBackoff(func, options) {

Expand All @@ -49,6 +49,7 @@ function expBackoff(func, options) {
var previousError = null;
var retryDelay = null;
var oldRetryDelay = null;
var customError;

// execute func() then retry <retry> times at most if errors
for (var n = 0; n < retry; n++) {
Expand Down Expand Up @@ -105,6 +106,7 @@ function expBackoff(func, options) {
oldRetryDelay = retryDelay;
retryDelay = null;


// Process error retry
if (!isUrlFetchResponse && error.message) {
var variables = [];
Expand Down Expand Up @@ -132,26 +134,26 @@ function expBackoff(func, options) {
// Do not wait too long
if (retryDelay < 32000) continue;

ErrorHandler.logError(error, {
customError = ErrorHandler.logError(error, {
failReason: 'Retry delay > 31s',
context: "Exponential Backoff",
numberRetry: n,
retryDelay: retryDelay,
}, {doNotLogKnownErrors: options.doNotLogKnownErrors});

if (options.withSilentFailure) return null;
throw error;
if (options.throwOnFailure) throw customError;
return customError;
}


ErrorHandler.logError(error, {
customError = ErrorHandler.logError(error, {
failReason: 'No retry needed',
numberRetry: n,
context: "Exponential Backoff"
}, {doNotLogKnownErrors: options.doNotLogKnownErrors});

if (options.withSilentFailure) return null;
throw error;
if (options.throwOnFailure) throw customError;
return customError;
}

}
Expand All @@ -171,13 +173,13 @@ function expBackoff(func, options) {

// Investigate on errors that are still happening after 5 retries
// Especially error "Not Found" - does it make sense to retry on it?
ErrorHandler.logError(error, {
customError = ErrorHandler.logError(error, {
failReason: 'Max retries reached',
context: "Exponential Backoff"
}, {doNotLogKnownErrors: options.doNotLogKnownErrors});

if (options.withSilentFailure) return null;
throw error;
if (options.throwOnFailure) throw customError;
return customError;
}

/**
Expand All @@ -198,16 +200,34 @@ function urlFetchWithExpBackOff(url, params) {
});
}

/**
* @typedef {Error} ErrorHandler_.CustomError
*
* @property {{
* locale: string,
* originalMessage: string,
* knownError: boolean,
* variables: Array<{}>,
* errorName: string,
* reportLocation: {
* lineNumber: number
* filePath: string,
* },
* }} context
*/

/**
* If we simply log the error object, only the error message will be submitted to Stackdriver Logging
* Best to re-write the error as a new object to get lineNumber & stack trace
*
* @param {String || Error || {lineNumber: number, fileName: string, responseCode: string}} error
* @param {Object || {addonName: string}} [additionalParams]
*
*
* @param {{}} [options] - default to FALSE, use console.warn instead console.error
* @param {boolean} options.asWarning - default to FALSE, use console.warn instead console.error
* @param {boolean} options.doNotLogKnownErrors - default to FALSE, if true, will not log known errors to stackdriver
*
* @return {ErrorHandler_.CustomError}
*/
function logError(error, additionalParams, options) {
options = options || {};
Expand All @@ -219,9 +239,6 @@ function logError(error, additionalParams, options) {
var normalizedMessage = ErrorHandler.getNormalizedError(error.message, partialMatches);
var message = normalizedMessage || error.message;

// options.doNotLogKnownErrors
if (options.doNotLogKnownErrors && normalizedMessage) return;

var locale;
try {
locale = Session.getActiveUserLocale();
Expand All @@ -235,7 +252,7 @@ function logError(error, additionalParams, options) {
context: {
locale: locale || '',
originalMessage: error.message,
translated: !!normalizedMessage,
knownError: !!normalizedMessage,
}
};

Expand Down Expand Up @@ -285,8 +302,16 @@ function logError(error, additionalParams, options) {
}

// Send error to stackdriver log
if (options.asWarning) console.warn(log);
else console.error(log);
if (!options.doNotLogKnownErrors || !normalizedMessage) {
if (options.asWarning) console.warn(log);
else console.error(log);
}

// Return an error, with context
var customError = new Error(normalizedMessage || error.message);
customError.context = log.context;

return customError;
}


Expand Down

0 comments on commit f0151ae

Please sign in to comment.