rate-limit-redis: PromiseRejectionHandledWarning: Promise rejection was handled asynchronously

Description

I get the following error the first time a request comes in:

(node:66707) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 4)
    at handledRejection (node:internal/process/promises:172:23)
    at promiseRejectHandler (node:internal/process/promises:118:7)
    at evalCommand (...)
    at RedisStore.runCommandWithRetry (...)
    at RedisStore.increment (...)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async node_modules/express-rate-limit/dist/index.cjs:553:5

Possibly because of a missing await here: https://github.com/express-rate-limit/rate-limit-redis/blob/f9b187878a554a89495c349e43a31af17abcb731/source/lib.ts#L110C14-L110C14

Library version

^6.10.0

Node version

v18.12.1

Typescript version (if you are using it)

5.0.4

Module system

CommonJS

About this issue

  • Original URL
  • State: open
  • Created 10 months ago
  • Reactions: 1
  • Comments: 15 (9 by maintainers)

Most upvoted comments

Okay I’m sorry, I don’t think it’s possible today

That’s fine.

FYI, by making sure that the redis connection is established before constructing an instance RedisStore got rid of the warning. The lack of a connection during construction was the issue all along for me.

Thanks, this helped fix the odd 504s when the redis store was used to rate limit a cluster behind a load balancer.

Here’s a snippet for the reference:

import { promisify } from "util";
import { rateLimit } from "express-rate-limit";
import RedisStore from "rate-limit-redis";
// your client config, something like const redisClient = new RedisClient(...);
import { redisClient } from "../redis";

let store: RedisStore | undefined = undefined;

async function initializeRateLimitStore() {
  try {
    const ping = promisify(redisClient.ping).bind(redisClient);
    await ping();
    store = new RedisStore({
      // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis
      sendCommand: (...args: string[]) => redisClient.call(...args),
    });
  } catch (err) {
    // log and handle
  }
}

(async () => {
  await initializeRateLimitStore();
})();

const redisLimit = rateLimit({
  store,
  // rest of your init params ...
})

versions: rate-limit-redis@^4.0.0, express-rate-limit@^7.0.1

Great! I’ll work on a PR for the same.

Also, I think it should be possible to propagate an error back, any error thrown within the middleware should be passed to the error handler defined for express.

Okay I’m sorry, I don’t think it’s possible today

That’s fine.

FYI, by making sure that the redis connection is established before constructing an instance RedisStore got rid of the warning. The lack of a connection during construction was the issue all along for me.