Comparing version 1.2.0 to 1.3.0
{ | ||
"name": "polly-js", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"description": "Transient exception handling", | ||
@@ -36,6 +36,6 @@ "main": "src/polly.js", | ||
"gulp-mocha": "^2.1.3", | ||
"istanbul": "^0.3.21", | ||
"istanbul": "^0.4.1", | ||
"mocha": "^2.3.2", | ||
"request-promise": "^0.4.3" | ||
"request-promise": "^1.0.2" | ||
} | ||
} |
@@ -17,6 +17,6 @@ # polly-js | ||
Try to load the Google home page and retry twice if it fails | ||
Try to load the Google home page and retry twice if it fails. | ||
```JavaScript | ||
polly | ||
polly() | ||
.retry(2) | ||
@@ -33,4 +33,6 @@ .executeForPromise(function () { | ||
Try to read a file from disk and retry twice if this fails. | ||
```JavaScript | ||
polly | ||
polly() | ||
.retry(2) | ||
@@ -48,4 +50,23 @@ .executeForNode(function (cb) { | ||
Only retry 'no such file or directory' errors. Wait 100 ms before retrying. | ||
```JavaScript | ||
polly() | ||
.handle(function(err) { | ||
return err.code === 'ENOENT' && err.errno === -4058; | ||
}) | ||
.waitAndRetry() | ||
.executeForNode(function (cb) { | ||
fs.readFile(path.join(__dirname, './not-there.txt'), cb); | ||
}, function (err, data) { | ||
if (err) { | ||
console.error('Failed trying twice with a 100ms delay', err) | ||
} else { | ||
console.log(data) | ||
} | ||
}); | ||
``` | ||
## Acknowledgements | ||
The library is based on the [Polly NuGet package](https://www.nuget.org/packages/Polly/) by Michael Wolfenden |
115
src/polly.js
@@ -21,2 +21,6 @@ /** | ||
var defaults = { | ||
delay: 100 | ||
}; | ||
function execute(config, cb) { | ||
@@ -30,3 +34,3 @@ var count = 0; | ||
catch (ex) { | ||
if (count < config.count) { | ||
if (count < config.count && config.handleFn(ex)) { | ||
count++; | ||
@@ -50,3 +54,3 @@ } else { | ||
}, function (e) { | ||
if (count < config.count) { | ||
if (count < config.count && config.handleFn(e)) { | ||
count++; | ||
@@ -64,2 +68,26 @@ execute(); | ||
function executeForPromiseWithDelay(config, cb) { | ||
return new Promise(function (resolve, reject) { | ||
function execute() { | ||
var original = cb(); | ||
original.then(function (e) { | ||
resolve(e); | ||
}, function (e) { | ||
var delay = config.delays.shift(); | ||
if (delay && config.handleFn(e)) { | ||
setTimeout(execute, delay); | ||
} else { | ||
reject(e); | ||
} | ||
}) | ||
} | ||
execute(); | ||
}); | ||
} | ||
function executeForNode(config, fn, callback) { | ||
@@ -69,3 +97,3 @@ var count = 0; | ||
function internalCallback(err, data) { | ||
if (err && count < config.count) { | ||
if (err && count < config.count && config.handleFn(err)) { | ||
count++; | ||
@@ -82,15 +110,76 @@ fn(internalCallback); | ||
return { | ||
retry: function (count) { | ||
var config = { | ||
count: count || 1 | ||
}; | ||
function executeForNodeWithDelay(config, fn, callback) { | ||
return { | ||
execute: execute.bind(null, config), | ||
executeForPromise: executeForPromise.bind(null, config), | ||
executeForNode: executeForNode.bind(null, config) | ||
}; | ||
function internalCallback(err, data) { | ||
var delay = config.delays.shift(); | ||
if (err && delay && config.handleFn(err)) { | ||
setTimeout(function () { | ||
fn(internalCallback); | ||
}, delay); | ||
} else { | ||
callback(err, data); | ||
} | ||
} | ||
fn(internalCallback); | ||
} | ||
function delayCountToDelays(count) { | ||
var delays = [], delay = defaults.delay; | ||
for (var i = 0; i < count; i++) { | ||
delays.push(delay); | ||
delay = 2 * delay; | ||
} | ||
return delays; | ||
} | ||
var pollyFn = function () { | ||
var config = { | ||
count: 1, | ||
delays: [defaults.delay], | ||
handleFn: function () { | ||
return true; | ||
} | ||
}; | ||
return { | ||
handle: function (handleFn) { | ||
if (typeof handleFn === 'function') { | ||
config.handleFn = handleFn; | ||
} | ||
return this; | ||
}, | ||
retry: function (count) { | ||
if (Number.isInteger(count)) { | ||
config.count = count; | ||
} | ||
return { | ||
execute: execute.bind(null, config), | ||
executeForPromise: executeForPromise.bind(null, config), | ||
executeForNode: executeForNode.bind(null, config) | ||
}; | ||
}, | ||
waitAndRetry: function (delays) { | ||
if (Number.isInteger(delays)) { | ||
delays = delayCountToDelays(delays); | ||
} | ||
if (Array.isArray(delays)) { | ||
config.delays = delays; | ||
} | ||
return { | ||
executeForPromise: executeForPromiseWithDelay.bind(null, config), | ||
executeForNode: executeForNodeWithDelay.bind(null, config) | ||
}; | ||
} | ||
}; | ||
}; | ||
pollyFn.defaults = defaults; | ||
return pollyFn; | ||
})); |
@@ -5,3 +5,2 @@ 'use strict'; | ||
var chaiAsPromised = require('chai-as-promised'); | ||
//var requestPromise = require('request-promise'); | ||
var fs = require('fs'); | ||
@@ -18,3 +17,3 @@ var path = require('path'); | ||
polly | ||
polly() | ||
.retry() | ||
@@ -32,3 +31,3 @@ .executeForNode(function (cb) { | ||
polly | ||
polly() | ||
.retry() | ||
@@ -48,3 +47,3 @@ .executeForNode(function (cb) { | ||
polly | ||
polly() | ||
.retry() | ||
@@ -66,3 +65,3 @@ .executeForNode(function (cb) { | ||
polly | ||
polly() | ||
.retry(5) | ||
@@ -84,3 +83,3 @@ .executeForNode(function (cb) { | ||
polly | ||
polly() | ||
.retry() | ||
@@ -103,6 +102,6 @@ .executeForNode(function (cb) { | ||
it('should retry four times after an error and succeed', function(done ) { | ||
it('should retry four times after an error and succeed', function (done) { | ||
var count = 0; | ||
polly | ||
polly() | ||
.retry(5) | ||
@@ -116,3 +115,3 @@ .executeForNode(function (cb) { | ||
} | ||
}, function(err, data) { | ||
}, function (err, data) { | ||
should.not.exist(err); | ||
@@ -124,2 +123,42 @@ data.should.equal(42); | ||
}); | ||
it('should retry five times if handling the error after an error and still fail', function (done) { | ||
var count = 0; | ||
polly() | ||
.handle(function(){ | ||
return true; | ||
}) | ||
.retry(5) | ||
.executeForNode(function (cb) { | ||
count++; | ||
fs.readFile(path.join(__dirname, './not-there.txt'), cb); | ||
}, function (err, data) { | ||
should.exist(err); | ||
err.should.be.instanceof(Error); | ||
should.not.exist(data); | ||
count.should.equal(6); | ||
done(); | ||
}); | ||
}); | ||
it('should not retry if not handling the error and still fail', function (done) { | ||
var count = 0; | ||
polly() | ||
.handle(function(){ | ||
return false; | ||
}) | ||
.retry(5) | ||
.executeForNode(function (cb) { | ||
count++; | ||
fs.readFile(path.join(__dirname, './not-there.txt'), cb); | ||
}, function (err, data) { | ||
should.exist(err); | ||
err.should.be.instanceof(Error); | ||
should.not.exist(data); | ||
count.should.equal(1); | ||
done(); | ||
}); | ||
}); | ||
}); |
@@ -15,3 +15,3 @@ 'use strict'; | ||
return polly | ||
return polly() | ||
.retry() | ||
@@ -26,3 +26,3 @@ .executeForPromise(function () { | ||
return polly | ||
return polly() | ||
.retry() | ||
@@ -39,3 +39,3 @@ .executeForPromise(function () { | ||
return polly | ||
return polly() | ||
.retry() | ||
@@ -58,3 +58,3 @@ .executeForPromise(function () { | ||
return polly | ||
return polly() | ||
.retry(5) | ||
@@ -77,3 +77,3 @@ .executeForPromise(function () { | ||
return polly | ||
return polly() | ||
.retry() | ||
@@ -99,3 +99,3 @@ .executeForPromise(function () { | ||
return polly | ||
return polly() | ||
.retry(5) | ||
@@ -121,3 +121,3 @@ .executeForPromise(function () { | ||
return polly | ||
return polly() | ||
.retry() | ||
@@ -137,3 +137,3 @@ .executeForPromise(function () { | ||
return polly | ||
return polly() | ||
.retry() | ||
@@ -149,2 +149,44 @@ .executeForPromise(function () { | ||
}); | ||
it('should retry five times if handling the error after an error and still fail', function () { | ||
var count = 0; | ||
return polly() | ||
.handle(function () { | ||
return true; | ||
}) | ||
.retry(5) | ||
.executeForPromise(function () { | ||
return new Promise(function (resolve, reject) { | ||
count++; | ||
reject(new Error("Wrong value")); | ||
}); | ||
}) | ||
.should.eventually | ||
.be.rejected | ||
.then(function () { | ||
count.should.equal(6); | ||
}); | ||
}); | ||
it('should not retry if not handling the error and still fail', function () { | ||
var count = 0; | ||
return polly() | ||
.handle(function () { | ||
return false; | ||
}) | ||
.retry(5) | ||
.executeForPromise(function () { | ||
return new Promise(function (resolve, reject) { | ||
count++; | ||
reject(new Error("Wrong value")); | ||
}); | ||
}) | ||
.should.eventually | ||
.be.rejected | ||
.then(function () { | ||
count.should.equal(1); | ||
}); | ||
}); | ||
}); |
@@ -9,3 +9,3 @@ 'use strict'; | ||
var result = polly | ||
var result = polly() | ||
.retry() | ||
@@ -22,3 +22,3 @@ .execute(function () { | ||
(function () { | ||
polly | ||
polly() | ||
.retry() | ||
@@ -35,3 +35,3 @@ .execute(function () { | ||
try { | ||
polly | ||
polly() | ||
.retry() | ||
@@ -53,3 +53,3 @@ .execute(function () { | ||
try { | ||
polly | ||
polly() | ||
.retry(5) | ||
@@ -70,3 +70,3 @@ .execute(function () { | ||
var result = polly | ||
var result = polly() | ||
.retry() | ||
@@ -89,3 +89,3 @@ .execute(function () { | ||
var result = polly | ||
var result = polly() | ||
.retry(5) | ||
@@ -104,3 +104,81 @@ .execute(function () { | ||
}); | ||
it('should retry five times after an error and still fail when all should be handled', function () { | ||
var count = 0; | ||
try { | ||
polly() | ||
.handle(function() { | ||
return true; | ||
}) | ||
.retry(5) | ||
.execute(function () { | ||
count++; | ||
throw new Error("Wrong value"); | ||
}); | ||
} | ||
catch (ex) { | ||
} | ||
count.should.equal(6); | ||
}); | ||
it('should not retry times after an error and still fail when none should be handled', function () { | ||
var count = 0; | ||
try { | ||
polly() | ||
.handle(function() { | ||
return false; | ||
}) | ||
.retry(5) | ||
.execute(function () { | ||
count++; | ||
throw new Error("Wrong value"); | ||
}); | ||
} | ||
catch (ex) { | ||
} | ||
count.should.equal(1); | ||
}); | ||
it('should retry 2 times after an error and still fail when all should be handled', function () { | ||
var count = 0; | ||
try { | ||
polly() | ||
.handle(function() { | ||
return count <= 2; | ||
}) | ||
.retry(5) | ||
.execute(function () { | ||
count++; | ||
throw new Error("Wrong value"); | ||
}); | ||
} | ||
catch (ex) { | ||
} | ||
count.should.equal(3); | ||
}); | ||
it('ignore the handle call if it isnt parameter a function', function () { | ||
var count = 0; | ||
try { | ||
polly() | ||
.handle() | ||
.retry(5) | ||
.execute(function () { | ||
count++; | ||
throw new Error("Wrong value"); | ||
}); | ||
} | ||
catch (ex) { | ||
} | ||
count.should.equal(6); | ||
}); | ||
}); | ||
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
270700
27
912
70
0
2