Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ReplyError: ERR invalid DB index #74

Closed
kimmobrunfeldt opened this issue Jun 16, 2015 · 5 comments
Closed

ReplyError: ERR invalid DB index #74

kimmobrunfeldt opened this issue Jun 16, 2015 · 5 comments

Comments

@kimmobrunfeldt
Copy link

When using ioredis in Heroku using RedisToGo add-on, I get this error:

Unhandled rejection ReplyError: ERR invalid DB index 
    at ReplyParser._parseResult (/app/node_modules/ioredis/lib/parsers/javascript.js:56:14) 
    at ReplyParser.execute (/app/node_modules/ioredis/lib/parsers/javascript.js:174:20) 
    at Socket.<anonymous> (/app/node_modules/ioredis/lib/redis/event_handler.js:88:22) 
    at Socket.emit (events.js:107:17) 
    at readableAddChunk (_stream_readable.js:163:16) 
    at Socket.Readable.push (_stream_readable.js:126:10) 
    at TCP.onread (net.js:538:20) 

Everything works fine on my local machine(OS X) and local redis. I'm testing this with free plan in RedisToGo.

I'm initializing ioredis(version 1.5.0) like this:

        var redis = new Redis(process.env.REDIS_URL, {
            retryStrategy: function(times) {
                // Make reconnecting a bit more relaxed compared to default
                var delay = Math.min(times * 100, 4000);
                return delay;
            }
        });
  • REDIS_URL in heroku is in format: redis://redistogo:<secret>@<secret>.redistogo.com:<port>/.
  • REDIS_URL in local is: redis://127.0.0.1:6379

Do you have ideas of how to fix this? Redis works apparently correctly but my logs fill up with those exceptions and in general I'd like to get this resolved.

@kimmobrunfeldt
Copy link
Author

By setting the database to 0 in the url: redis://redistogo:<secret>@<secret>.redistogo.com:<port>/0 the issue goes away.

@kimmobrunfeldt
Copy link
Author

This might be an bug in parsing urls with trailing slash. Quote from RedisToGo support:

Just wanted to send you a bit more information, as I did some digging into the driver code and I have found the source of the issue. Here is some sample code from the node shell that should explain things:

var urllib = require('url');
var Redis = require('ioredis');

// Explicit database 0
> var redis = Redis('redis://redistogo:mypassword@myhost.redistogo.com:54321/0');
undefined
> redis.get('foo', function(err, result){console.log(result);});
{ _bitField: 1,
  _fulfillmentHandler0: [Function: successAdapter],
  _rejectionHandler0: [Function: errorAdapter],
  _progressHandler0: undefined,
  _promise0: [Function],
  _receiver0: [Circular],
  _settledValue: undefined }
> bar

// Implied database 0
> var redis2 = Redis('redis://redistogo:mypassword@myhost.redistogo.com:54321');
undefined
> redis2.get('foo', function(err, result){console.log(result);});
{ _bitField: 1,
  _fulfillmentHandler0: [Function: successAdapter],
  _rejectionHandler0: [Function: errorAdapter],
  _progressHandler0: undefined,
  _promise0: [Function],
  _receiver0: [Circular],
  _settledValue: undefined }
> bar

// Force parse error
> var redis3 = Redis('redis://redistogo:mypassword@myhost.redistogo.com:54321/');
undefined
> Unhandled rejection ReplyError: ERR invalid DB index
    at ReplyParser._parseResult (/mycomputer/vault/code/node_realm/node_modules/ioredis/lib/parsers/javascript.js:56:14)
    at ReplyParser.execute (/mycomputer/vault/code/node_realm/node_modules/ioredis/lib/parsers/javascript.js:174:20)
    at Socket.<anonymous> (/mycomputer/vault/code/node_realm/node_modules/ioredis/lib/redis/event_handler.js:88:22)
    at Socket.emit (events.js:107:17)
    at readableAddChunk (_stream_readable.js:163:16)
    at Socket.Readable.push (_stream_readable.js:126:10)
    at TCP.onread (net.js:538:20)
> redis3.get('foo', function(err, result){console.log(result);});
{ _bitField: 1,
  _fulfillmentHandler0: [Function: successAdapter],
  _rejectionHandler0: [Function: errorAdapter],
  _progressHandler0: undefined,
  _promise0: [Function],
  _receiver0: [Circular],
  _settledValue: undefined }
> bar

// Different parsed URLs
> var p = url.parse('redis://redistogo:mypassword@myhost.redistogo.com:54321/0');
undefined
> p
{ protocol: 'redis:',
  slashes: true,
  auth: 'redistogo:mypassword',
  host: 'myhost.redistogo.com:54321',
  port: '54321',
  hostname: 'myhost.redistogo.com',
  hash: null,
  search: null,
  query: null,
  pathname: '/0',
  path: '/0',
  href: 'redis://redistogo:mypassword@myhost.redistogo.com:54321/0' }
> p.pathname.slice(1)
0

> var p2 = url.parse('redis://redistogo:mypassword@myhost.redistogo.com:54321');
undefined
> p2
{ protocol: 'redis:',
  slashes: true,
  auth: 'redistogo:mypassword',
  host: 'myhost.redistogo.com:54321',
  port: '54321',
  hostname: 'myhost.redistogo.com',
  hash: null,
  search: null,
  query: null,
  pathname: null,
  path: null,
  href: 'redis://redistogo:mypassword@myhost.redistogo.com:54321' }
// p2.pathname is null, won't call .split(1) and _.defaults will be called
// See code below
// https://github.com/luin/ioredis/blob/master/lib/utils/index.js#L254-L285

> var p3 = url.parse('redis://redistogo:mypassword@myhost.redistogo.com:54321/');
undefined
> p3
{ protocol: 'redis:',
  slashes: true,
  auth: 'redistogo:mypassword',
  host: 'myhost.redistogo.com:54321',
  port: '54321',
  hostname: 'myhost.redistogo.com',
  hash: null,
  search: null,
  query: null,
  pathname: '/',
  path: '/',
  href: 'redis://redistogo:mypassword@myhost.redistogo.com:54321/' }
> p3.pathname.slice(1)
''

Looking through the documentation for the driver they list a trailing slash as a valid URL, but in this driver it is not handled correctly. Here is the example in the docs:

https://github.com/luin/ioredis/blob/master/lib/redis.js#L84

My proposed solution would be to modify this code:

https://github.com/luin/ioredis/blob/master/lib/utils/index.js#L270-L272

if (parsed.protocol === 'redis:') {
    result.db = (parsed.pathname !== '/')
      ? parsed.pathname.slice(1)
      : '0';
}

I hope this helps explain things but please let me know if you have any further questions.

Thank you,
~John Moore
RedisToGo Support

@nakulgan
Copy link
Contributor

Any idea what Version of Redis they're running at redistogo.com?
SELECT '' seems to be valid on >Redis 2.4 and defaults to 0.

@luin luin closed this as completed in 5ce708a Jun 16, 2015
@luin
Copy link
Collaborator

luin commented Jun 16, 2015

It's a bug that getting a NaN db when the pathname is empty. Fixed in 1.5.1. Thanks for pointing it out.

sgress454 added a commit to balderdashy/sails that referenced this issue Dec 6, 2016
Trailing slashes have been known to cause issues with some hosted Redis providers.  See redis/ioredis#74 (comment)
@theronic
Copy link

This still happens on Heroku using v4.16.3. Adding /0 to the end of the Redis URL makes it go away.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants