redis / redis-rb

A Ruby client library for Redis
MIT License
3.97k stars 1.03k forks source link

`ERR value is not an integer or out of range` after redis.ping #1235

Closed yart closed 10 months ago

yart commented 10 months ago

My case:

options = {
  host: Rails.env.production? ? 'xxx.xxx.xxx.xxx' : 'run_redis_dev',
  db: 'robotix_max_bot',
  port: 6379
}

REDIS = Redis.new(**options)

Redis runs in a Docker container with the same network as my app's container.

Then I'm running rails c:

[1] pry(main)> r = REDIS
=> #<Redis client v5.0.8 for redis://run_redis_dev:6379/robotix_max_bot>
[2] pry(main)> r.ping
Redis::CommandError: ERR value is not an integer or out of range
from /usr/local/bundle/gems/redis-client-0.18.0/lib/redis_client/connection_mixin.rb:61:in `call_pipelined'
Caused by RedisClient::CommandError: ERR value is not an integer or out of range
from /usr/local/bundle/gems/redis-client-0.18.0/lib/redis_client/connection_mixin.rb:61:in `call_pipelined'
[3] pry(main)> r.ping
=> "PONG"

Why is this happening? The first call provides the error, and then it goes smoothly always 'till restart the app.

[4] pry(main)> r.set("mykey", "hello world")
=> "OK"
[5] pry(main)> r.get("mykey")
=> "hello world"

Of course, I can catch this Exception, but in my opinion, this isn't the best practice in this case. Can anybody tell me what am I doing wrong?

My Gemfile:

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '3.0.6'

gem 'bootsnap', require: false
gem 'pg', '>=1.5.4'
gem 'puma', '~> 5.0'
gem 'rails', '~> 7.0.2', '>= 7.0.2.3'
gem 'redis', '>=5.0.8'
gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]

gem 'telegram-bot', git: 'https://github.com/telegram-bot-rb/telegram-bot.git', branch: 'master'
# gem 'telegram-bot', '0.15.7'

group :development, :test do
  gem 'awesome_print'
  gem 'debug', platforms: %i[mri mingw x64_mingw]
  gem 'hirb'
  gem 'pry'
  gem 'pry-byebug', platforms: [:mri]
  gem 'pry-doc', platforms: [:mri]
  gem 'pry-nav', platforms: [:jruby]
  gem 'pry-rails'
  gem 'rspec-its'
  gem 'rspec-rails'
  gem 'spring-commands-rspec'
end
byroot commented 10 months ago
[2] pry(main)> r.ping
Redis::CommandError: ERR value is not an integer or out of range
from /usr/local/bundle/gems/redis-client-0.18.0/lib/redis_client/connection_mixin.rb:61:in `call_pipelined'
Caused by RedisClient::CommandError: ERR value is not an integer or out of range
from /usr/local/bundle/gems/redis-client-0.18.0/lib/redis_client/connection_mixin.rb:61:in `call_pipelined'

Could you provide the full backtrace here?

>> error = (r.ping rescue $!)
>> puts error.backtrace

For some reason r.ping end up calling a pipeline which makes little sense I suspect you have some monkey patch of some sort in your app or one of you dependencies.

yart commented 10 months ago

@byroot, please loot at this:

[1] pry(main)> r = REDIS
=> #<Redis client v5.0.8 for redis://run_redis_dev:6379/robotix_max_bot>
[2] pry(main)> error = (r.ping rescue $!)
=> #<Redis::CommandError: ERR value is not an integer or out of range>
[3] pry(main)> puts error.backtrace
/usr/local/bundle/gems/redis-client-0.18.0/lib/redis_client/connection_mixin.rb:61:in `call_pipelined'
/usr/local/bundle/gems/redis-client-0.18.0/lib/redis_client.rb:745:in `block in connect'
/usr/local/bundle/gems/redis-client-0.18.0/lib/redis_client/middlewares.rb:16:in `call'
/usr/local/bundle/gems/redis-client-0.18.0/lib/redis_client.rb:744:in `connect'
/usr/local/bundle/gems/redis-client-0.18.0/lib/redis_client.rb:706:in `raw_connection'
/usr/local/bundle/gems/redis-client-0.18.0/lib/redis_client.rb:673:in `ensure_connected'
/usr/local/bundle/gems/redis-client-0.18.0/lib/redis_client.rb:269:in `call_v'
/usr/local/bundle/gems/redis-5.0.8/lib/redis/client.rb:90:in `call_v'
/usr/local/bundle/gems/redis-5.0.8/lib/redis.rb:152:in `block in send_command'
/usr/local/bundle/gems/redis-5.0.8/lib/redis.rb:151:in `synchronize'
/usr/local/bundle/gems/redis-5.0.8/lib/redis.rb:151:in `send_command'
/usr/local/bundle/gems/redis-5.0.8/lib/redis/commands/connection.rb:21:in `ping'
(pry):2:in `__pry__'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/pry_instance.rb:290:in `eval'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/pry_instance.rb:290:in `evaluate_ruby'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/pry_instance.rb:659:in `handle_line'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/pry_instance.rb:261:in `block (2 levels) in eval'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/pry_instance.rb:260:in `catch'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/pry_instance.rb:260:in `block in eval'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/pry_instance.rb:259:in `catch'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/pry_instance.rb:259:in `eval'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/repl.rb:77:in `block in repl'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/repl.rb:67:in `loop'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/repl.rb:67:in `repl'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/repl.rb:38:in `block in start'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/input_lock.rb:61:in `__with_ownership'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/input_lock.rb:78:in `with_ownership'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/repl.rb:38:in `start'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/repl.rb:15:in `start'
/usr/local/bundle/gems/pry-byebug-3.10.1/lib/pry-byebug/pry_ext.rb:15:in `start_with_pry_byebug'
/usr/local/bundle/gems/pry-0.14.2/lib/pry/pry_class.rb:194:in `start'
/usr/local/bundle/gems/railties-7.0.8/lib/rails/commands/console/console_command.rb:74:in `start'
/usr/local/bundle/gems/railties-7.0.8/lib/rails/commands/console/console_command.rb:19:in `start'
/usr/local/bundle/gems/railties-7.0.8/lib/rails/commands/console/console_command.rb:106:in `perform'
/usr/local/bundle/gems/thor-1.3.0/lib/thor/command.rb:28:in `run'
/usr/local/bundle/gems/thor-1.3.0/lib/thor/invocation.rb:127:in `invoke_command'
/usr/local/bundle/gems/thor-1.3.0/lib/thor.rb:527:in `dispatch'
/usr/local/bundle/gems/railties-7.0.8/lib/rails/command/base.rb:87:in `perform'
/usr/local/bundle/gems/railties-7.0.8/lib/rails/command.rb:48:in `invoke'
/usr/local/bundle/gems/railties-7.0.8/lib/rails/commands.rb:18:in `<top (required)>'
<internal:/usr/local/lib/ruby/site_ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
<internal:/usr/local/lib/ruby/site_ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
bin/rails:4:in `<main>'
=> nil
byroot commented 10 months ago

Ok, it fails as part of the connection prelude and based on the error message I would hasard the guess that you are passing a db: parameter that isn't an Integer.

It's actually visible in what you posted initially: redis://run_redis_dev:6379/robotix_max_bot here robotix_max_bot is treaded as the DB index, and can't be converted to integer. Just remove that part of the URL, or explictly pass a db: 0 parameter to overwrite it.

That said, redis-client should fail sooner with a cleaner error when this mistake is made, so I'll keep the issue open until I improve that.

yart commented 10 months ago

explictly pass a db: 0 parameter to overwrite it.

OMG! :man_facepalming: My mistake. Thanks for the explanation and fix.