lib/redis/client.rb
# frozen_string_literal: true class Redis class Client < ::RedisClient ERROR_MAPPING = { RedisClient::ConnectionError => Redis::ConnectionError, RedisClient::CommandError => Redis::CommandError, RedisClient::ReadTimeoutError => Redis::TimeoutError, RedisClient::CannotConnectError => Redis::CannotConnectError, RedisClient::AuthenticationError => Redis::CannotConnectError, RedisClient::FailoverError => Redis::CannotConnectError, RedisClient::PermissionError => Redis::PermissionError, RedisClient::WrongTypeError => Redis::WrongTypeError, RedisClient::ReadOnlyError => Redis::ReadOnlyError, RedisClient::ProtocolError => Redis::ProtocolError, RedisClient::OutOfMemoryError => Redis::OutOfMemoryError, } if defined?(RedisClient::NoScriptError) ERROR_MAPPING[RedisClient::NoScriptError] = Redis::NoScriptError end class << self def config(**kwargs) super(protocol: 2, **kwargs) end def sentinel(**kwargs) super(protocol: 2, **kwargs, client_implementation: ::RedisClient) end def translate_error!(error, mapping: ERROR_MAPPING) redis_error = translate_error_class(error.class, mapping: mapping) raise redis_error, error.message, error.backtrace end private def translate_error_class(error_class, mapping: ERROR_MAPPING) mapping.fetch(error_class) rescue IndexError if (client_error = error_class.ancestors.find { |a| mapping[a] }) mapping[error_class] = mapping[client_error] else raise end end end def id config.id end def server_url config.server_url end def timeout config.read_timeout end def db config.db end def host config.host unless config.path end def port config.port unless config.path end def path config.path end def username config.username end def password config.password end undef_method :call undef_method :call_once undef_method :call_once_v undef_method :blocking_call def ensure_connected(retryable: true, &block) super(retryable: retryable, &block) rescue ::RedisClient::Error => error Client.translate_error!(error) end def call_v(command, &block) super(command, &block) rescue ::RedisClient::Error => error Client.translate_error!(error) end def blocking_call_v(timeout, command, &block) if timeout && timeout > 0 # Can't use the command timeout argument as the connection timeout # otherwise it would be very racy. So we add the regular read_timeout on top # to account for the network delay. timeout += config.read_timeout end super(timeout, command, &block) rescue ::RedisClient::Error => error Client.translate_error!(error) end def pipelined(exception: true) super rescue ::RedisClient::Error => error Client.translate_error!(error) end def multi(watch: nil) super rescue ::RedisClient::Error => error Client.translate_error!(error) end def inherit_socket! @inherit_socket = true end end end