From 3ca30d8499c1ccfe4dff7b46fc2bcfc16f704e1d Mon Sep 17 00:00:00 2001 From: luin Date: Sun, 10 Apr 2016 23:49:20 +0800 Subject: [PATCH] fix(sentinel): improve the error message when connection to sentinel is rejected Closes #280 --- lib/connectors/sentinel_connector.js | 11 +++++++++-- lib/redis/parser.js | 2 +- test/functional/sentinel.js | 25 +++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/lib/connectors/sentinel_connector.js b/lib/connectors/sentinel_connector.js index 44a8cb39..686fd08c 100644 --- a/lib/connectors/sentinel_connector.js +++ b/lib/connectors/sentinel_connector.js @@ -37,6 +37,7 @@ SentinelConnector.prototype.connect = function (callback) { } var _this = this; + var lastError; connectToNext(); function connectToNext() { @@ -50,7 +51,11 @@ SentinelConnector.prototype.connect = function (callback) { } if (typeof retryDelay !== 'number') { debug('All sentinels are unreachable and retry is disabled, emitting error...'); - return callback(new Error('All sentinels are unreachable.')); + var error = 'All sentinels are unreachable.'; + if (lastError) { + error += ' Last error: ' + lastError.message; + } + return callback(new Error(error)); } debug('All sentinels are unreachable. Retrying from scratch after %d', retryDelay); setTimeout(connectToNext, retryDelay); @@ -68,9 +73,11 @@ SentinelConnector.prototype.connect = function (callback) { callback(null, _this.stream); } else if (err) { debug('failed to connect to sentinel %s:%s because %s', endpoint.host, endpoint.port, err); + lastError = err; connectToNext(); } else { - debug('connected to sentinel %s:%s successfully, but got a invalid reply: %s', endpoint.host, endpoint.port, resolved); + debug('connected to sentinel %s:%s successfully, but got a invalid reply: %s', + endpoint.host, endpoint.port, resolved); connectToNext(); } }); diff --git a/lib/redis/parser.js b/lib/redis/parser.js index 4087f0f3..433ebbd8 100644 --- a/lib/redis/parser.js +++ b/lib/redis/parser.js @@ -148,7 +148,7 @@ exports.returnReply = function (reply) { item = this.commandQueue.shift(); if (!item) { return this.emit('error', - new Error('Command queue state error. If you can reproduce this, please report it.' + reply.toString())); + new Error('Command queue state error. If you can reproduce this, please report it. Last reply: ' + reply.toString())); } if (_.includes(Command.FLAGS.ENTER_SUBSCRIBER_MODE, item.command.name)) { this.condition.subscriber = new SubscriptionSet(); diff --git a/test/functional/sentinel.js b/test/functional/sentinel.js index 8bf690ac..470c9a73 100644 --- a/test/functional/sentinel.js +++ b/test/functional/sentinel.js @@ -129,6 +129,31 @@ describe('sentinel', function () { }); }); + it('should reject when sentinel is rejected', function (done) { + var sentinel = new MockServer(27379, function (argv) { + if (argv[0] === 'sentinel' && argv[1] === 'get-master-addr-by-name') { + return new Error('just rejected'); + } + }); + + var redis = new Redis({ + sentinels: [ + { host: '127.0.0.1', port: '27379' } + ], + name: 'master', + sentinelRetryStrategy: null, + lazyConnect: true + }); + + redis.connect().then(function () { + throw new Error('Expect `connect` to be thrown'); + }).catch(function (err) { + expect(err.message).to.eql('All sentinels are unreachable. Last error: just rejected'); + redis.disconnect(); + sentinel.disconnect(done); + }); + }); + it('should connect to the next sentinel if getting master failed', function (done) { var sentinel = new MockServer(27379, function (argv) { if (argv[0] === 'sentinel' && argv[1] === 'get-master-addr-by-name') {