summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGraeme Yeates <yeatesgraeme@gmail.com>2016-08-08 09:51:08 -0400
committerGitHub <noreply@github.com>2016-08-08 09:51:08 -0400
commitff65da5bb3b14fc7ba4632859fa9a0eee73ae80c (patch)
tree51dd8638db6ce4a520b4ef6955251d19a63ef15d /lib
parent8ea5ea8b9a229882e82e08287bb68a28fd4ecd2f (diff)
parent4367751bc420f4f279d83e8eae291708bf7990f6 (diff)
downloadasync-ff65da5bb3b14fc7ba4632859fa9a0eee73ae80c.tar.gz
Merge pull request #1261 from bojand/master
add filter option to retry() and retryable(). PR for #1256.
Diffstat (limited to 'lib')
-rw-r--r--lib/retry.js23
1 files changed, 21 insertions, 2 deletions
diff --git a/lib/retry.js b/lib/retry.js
index 8163ad9..a5ad866 100644
--- a/lib/retry.js
+++ b/lib/retry.js
@@ -19,6 +19,11 @@ import constant from 'lodash/constant';
* * `interval` - The time to wait between retries, in milliseconds. The
* default is `0`. The interval may also be specified as a function of the
* retry count (see example).
+ * * `errorFilter` - An optional synchronous function that is invoked on
+ * erroneous result. If it returns `true` the retry attempts will continue;
+ * if the function returns `false` the retry flow is aborted with the current
+ * attempt's error and result being returned to the final callback.
+ * Invoked with (err).
* * If `opts` is a number, the number specifies the number of times to retry,
* with the default interval of `0`.
* @param {Function} task - A function which receives two arguments: (1) a
@@ -62,6 +67,16 @@ import constant from 'lodash/constant';
* // do something with the result
* });
*
+ * // try calling apiMethod only when error condition satisfies, all other
+ * // errors will abort the retry control flow and return to final callback
+ * async.retry({
+ * errorFilter: function(err) {
+ * return err.message === 'Temporary error'; // only retry on a specific error
+ * }
+ * }, apiMethod, function(err, result) {
+ * // do something with the result
+ * });
+ *
* // It can also be embedded within other control flow functions to retry
* // individual methods that are not as reliable, like this:
* async.auto({
@@ -70,6 +85,7 @@ import constant from 'lodash/constant';
* }, function(err, results) {
* // do something with the results
* });
+ *
*/
export default function retry(opts, task, callback) {
var DEFAULT_TIMES = 5;
@@ -87,6 +103,8 @@ export default function retry(opts, task, callback) {
acc.intervalFunc = typeof t.interval === 'function' ?
t.interval :
constant(+t.interval || DEFAULT_INTERVAL);
+
+ acc.errorFilter = t.errorFilter;
} else if (typeof t === 'number' || typeof t === 'string') {
acc.times = +t || DEFAULT_TIMES;
} else {
@@ -94,7 +112,6 @@ export default function retry(opts, task, callback) {
}
}
-
if (arguments.length < 3 && typeof opts === 'function') {
callback = task || noop;
task = opts;
@@ -110,7 +127,9 @@ export default function retry(opts, task, callback) {
var attempt = 1;
function retryAttempt() {
task(function(err) {
- if (err && attempt++ < options.times) {
+ if (err && attempt++ < options.times &&
+ (typeof options.errorFilter != 'function' ||
+ options.errorFilter(err))) {
setTimeout(retryAttempt, options.intervalFunc(attempt));
} else {
callback.apply(null, arguments);