From f2594d83ddc408d41d17c56e28221467047ca796 Mon Sep 17 00:00:00 2001 From: Lance Ball Date: Mon, 6 Mar 2017 17:15:59 -0500 Subject: [PATCH] fix: circuit should emit failure event on fallback Fixes: https://github.com/bucharest-gold/opossum/issues/28 --- lib/circuit.js | 12 ++++++------ test/test.js | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/lib/circuit.js b/lib/circuit.js index 26a1e7f7..5a45f8d4 100644 --- a/lib/circuit.js +++ b/lib/circuit.js @@ -178,8 +178,8 @@ class CircuitBreaker extends EventEmitter { * @event CircuitBreaker#reject */ this.emit('reject', new Error('Breaker is open')); - return fallback(this, 'Breaker is open', args) || - fail(this, 'Breaker is open', args); + const failure = fail(this, 'Breaker is open', args); + return fallback(this, 'Breaker is open', args) || failure; } this[PENDING_CLOSE] = this.halfOpen; @@ -218,15 +218,16 @@ class CircuitBreaker extends EventEmitter { }) .catch((error) => { clearTimeout(timeout); + fail(this, error, args); const fb = fallback(this, error, args); if (fb) return resolve(fb); - fail(this, error, args); - reject(error); + else reject(error); }); }); } catch (error) { clearTimeout(timeout); - return fallback(this, error, args) || fail(this, error, args); + fail(this, error, args); + return fallback(this, error, args); } } } @@ -257,7 +258,6 @@ function fail (circuit, err, args) { if (circuit[NUM_FAILURES] >= circuit.options.maxFailures) { circuit.open(); } - return circuit.Promise.reject.apply(null, [err]); } diff --git a/test/test.js b/test/test.js index 4c6a259e..5738c354 100644 --- a/test/test.js +++ b/test/test.js @@ -201,6 +201,19 @@ test('Returns self from fallback()', (t) => { .catch(t.fail); }); +test('CircuitBreaker emits failure when falling back', (t) => { + t.plan(2); + const breaker = cb(passFail).fallback(() => 'fallback value'); + + breaker.on('failure', (err) => { + t.equals(err, 'Error: -1 is < 0', 'Unexpected error'); + }); + + breaker.fire(-1).then((result) => { + t.equals('fallback value', result, 'fallback value is correct'); + }).catch(t.fail); +}); + test('CircuitBreaker status', (t) => { t.plan(11); const breaker = cb(passFail, { maxFailures: 1 }); @@ -226,12 +239,13 @@ test('CircuitBreaker status', (t) => { breaker.fire(-20) .then((result) => { t.equal(result, 'Fallback called', 'fallback is invoked'); - t.equal(breaker.status.failures, 1, 'status reports 1 failures'); + t.equal(breaker.status.failures, 2, 'status reports 2 failures'); t.equal(breaker.status.fires, 5, 'status reports 5 fires'); t.equal(breaker.status.fallbacks, 1, 'status reports 1 fallback'); }) .catch(t.fail); }) + .catch(t.fail) .then(t.end); }); });