redis / ioredis

🚀 A robust, performance-focused, and full-featured Redis client for Node.js.
MIT License
14.36k stars 1.19k forks source link

quit() error "connection is closed." only for TLS connection #1628

Open JoHuang opened 2 years ago

JoHuang commented 2 years ago

When connecting to Redis via TLS connection, calling quit() causes an unhandled error. No issue for non-TLS mode.

node.js : v16.15.0 ioredis version: 4.28.5, 4.28.0 tested with Redis.com and DigitalOcean managed Redis

    Error: Connection is closed.
        at close (/p/node_modules/ioredis/built/redis/event_handler.js:184:25)
        at TLSSocket.<anonymous> (/p/node_modules/ioredis/built/redis/event_handler.js:151:20)
        at Object.onceWrapper (node:events:642:26)
        at TLSSocket.emit (node:events:539:35)
        at TLSSocket.emit (node:domain:475:12)
        at node:net:709:12
        at TCP.done (node:_tls_wrap:582:7)

debug message:

  ioredis:redis status[redis-19201.c285.us-west-2-2.ec2.cloud.redislabs.com:19201]: [empty] -> wait +0ms
  ioredis:redis status[redis-19201.c285.us-west-2-2.ec2.cloud.redislabs.com:19201]: wait -> connecting +1ms
  ioredis:redis status[18.236.148.227:19201]: connecting -> connect +502ms
  ioredis:redis write command[18.236.148.227:19201]: 0 -> auth([ 'xxxxxxxxxxxxxxxxx' ]) +1ms
  ioredis:redis write command[18.236.148.227:19201]: 0 -> info([]) +4ms
  ioredis:redis status[18.236.148.227:19201]: connect -> ready +164ms
{"level":"info","time":1659510369171,"module":"DB","hostname":"My-MBP","message":"Redis server is ready."}
  ioredis:redis write command[18.236.148.227:19201]: 0 -> quit([]) +4s
  ioredis:redis status[18.236.148.227:19201]: ready -> close +269ms
  ioredis:connection skip reconnecting since the connection is manually closed. +0ms
  ioredis:redis status[18.236.148.227:19201]: close -> end +1ms
{"level":"error","time":1659510373773,"module":"DB","hostname":"My-MBP","stack":"Error: Connection is closed.\n    at close (/p/node_modules/ioredis/built/redis/event_handler.js:184:25)\n    at TLSSocket.<anonymous> (/p/node_modules/ioredis/built/redis/event_handler.js:151:20)\n    at Object.onceWrapper (node:events:642:26)\n    at TLSSocket.emit (node:events:539:35)\n    at TLSSocket.emit (node:domain:475:12)\n    at node:net:709:12\n    at TCP.done (node:_tls_wrap:582:7)","type":"Error","message":"unhandledRejection"}

non-TLS normal case:

  ioredis:redis status[redis-19201.c285.us-west-2-2.ec2.cloud.redislabs.com:19201]: [empty] -> wait +0ms
  ioredis:redis status[redis-19201.c285.us-west-2-2.ec2.cloud.redislabs.com:19201]: wait -> connecting +1ms
  ioredis:redis status[18.236.148.227:19201]: connecting -> connect +681ms
  ioredis:redis write command[18.236.148.227:19201]: 0 -> auth([ 'xxxxxxxxxxxx' ]) +3ms
  ioredis:redis write command[18.236.148.227:19201]: 0 -> info([]) +5ms
  ioredis:redis status[18.236.148.227:19201]: connect -> ready +166ms
{"level":"info","time":1659510285247,"module":"DB","hostname":"My-MBP","message":"Redis server is ready."}
  ioredis:redis write command[18.236.148.227:19201]: 0 -> quit([]) +4s
{"level":"info","time":1659510289553,"module":"DB","hostname":"My-MBP","message":"Redis server is closed. OK"}
  ioredis:redis status[18.236.148.227:19201]: ready -> close +164ms
  ioredis:connection skip reconnecting since the connection is manually closed. +0ms
  ioredis:redis status[18.236.148.227:19201]: close -> end +0ms
alesmenzel commented 1 year ago

Hi, the same error can happen when calling quit() on closed connection, e.g. due to termination from the redis server side. Would you please expose the connection status on redis client instance so we could conditionally call quit? Right now the workaround is to listen on close/end and other events to tract the connection status.