node-rate-limiter-flexible: Mongodb: Cannot read property 'points' of null at RateLimiterMongo._getRateLimiterRes

There seems to be an issue when using a clustered connection from MongoDB Atlas. I tried the same setup both on a local server and a mongodb Atlas server, there is always an error on the first consume when testing on the Atlas server.

Setup: “MongoDB”: 5.0.6 “Mongoose”: “^6.2.2”, “NodeJS” : 14.18.1

const limiterSlowBruteByIPOps = {
  keyPrefix: '',
  storeClient: dbConnection,
  tableName: 'login_fail_ip_per_day',
  points: maxConsecutiveFailsByAccountAndIP,
  duration: 60 * 60 * 24 * 90, // Store number for 90 days since first fail
  blockDuration: 60 * 60 * 24 * 365 * 20, // Block for infinity after consecutive
};

When using local server: Localhost

in RatelimiterMongo.js line 14

 _getRateLimiterRes(rlKey, changedPoints, result) {
    const res = new RateLimiterRes();

    let doc;
    if (typeof result.value === 'undefined') {
      doc = result;
    } else {
      doc = result.value;
    }

    **res.isFirstInDuration = doc.points === changedPoints;**
    res.consumedPoints = doc.points;
   ....
}

the result value coming in from the this._collection.findOneAndUpdate on the first consume looks like this

First consume call => no error on localhost
{
  lastErrorObject: {
    n: 1,
    updatedExisting: false,
    upserted: new ObjectId("621feaf6404e93c2a20983d7")
  },
  value: {
    _id: new ObjectId("621feaf6404e93c2a20983d7"),
    key: '::1',
    expire: 2022-05-31T22:08:54.769Z,
    points: 1
  },
  ok: 1
}

Second consume localhost call => no error on localhost

{
  lastErrorObject: {
    n: 1,
    updatedExisting: true
},
  value: {
    _id: new ObjectId("621fedca404e93c2a20985c4"),
    key: '::1',
    expire: 2022-05-31T22:20:58.609Z,
    points: 2
  },
  ok: 1
}

however, when testing with the mongoDB Cluster I get a different result format generating the error.

MongoDb Cluster

First consume to Atlas cluster always throw error

{
  lastErrorObject: {
    n: 1,
    updatedExisting: false,
    upserted: new ObjectId("621fec0568d6587a94266266")
  },
  value: null, // **value here is null and throws error on this line "res.isFirstInDuration = doc.points === changedPoints**;"
  ok: 1,
  '$clusterTime': {
    clusterTime: new Timestamp({ t: 1646259205, i: 3 }),
    signature: {
      hash: new Binary(Buffer.from("9406443ec068e13b88f3a0f867044c3d4d18afa0", "hex"), 0),
      keyId: new Long("7020773886748786690")
    }
  },
  operationTime: new Timestamp({ t: 1646259205, i: 3 })
}

Second consume to Atlas => no error

{
  lastErrorObject: {
		n: 1,
		updatedExisting: true
	},
  value: {
    _id: new ObjectId("621fec0568d6587a94266264"),
    key: '::1',
    expire: 2022-05-31T22:13:26.591Z,
    points: 1
  },
  ok: 1,
  '$clusterTime': {
    clusterTime: new Timestamp({ t: 1646259511, i: 4 }),
    signature: {
      hash: new Binary(Buffer.from("aebd4a7b566496affeb8c2bbb7622add8f84043d", "hex"), 0),
      keyId: new Long("7020773886748786690")
    }
  },
  operationTime: new Timestamp({ t: 1646259511, i: 4 })
}

Am I doing this wrong or is there a bug?

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 19 (8 by maintainers)

Most upvoted comments

This is happening to me when using rate-limiter-flexible (2.3.6), mongoose (6.2.7) and mongo-memory-server (8.4.1). I get the exact same error message, and my solution is the same – downgrading to mongoose 5.X solves the issue. This leads to me to assume this is not an atlas issue specifically.