Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why I was getting "Jest has detected the following 1 open handle potentially keeping Jest from exiting: Timeout" #823

Open
isaacgr opened this issue May 25, 2023 · 0 comments

Comments

@isaacgr
Copy link

isaacgr commented May 25, 2023

Not a bug. Just wanted to document this here in case anyone else comes across the same issue. When running my tests I was getting the below output:

Jest has detected the following 1 open handle potentially keeping Jest from exiting:

  ●  Timeout

      41 |      describe("responses", () => {
      42 |              it("should send a 200 response for a valid request", async () => {
    > 43 |                      const response = await request(app).get(
         |                                                          ^
      44 |                              `/api/${apiVersion}${ROUTE_PATHS.PARTNUMBERS}`
      45 |                      );
      46 |                      // console.log(request(app).get("/").serverAddress(app, "/"));

      at Test.serverAddress (node_modules/supertest/lib/test.js:48:35)
      at new Test (node_modules/supertest/lib/test.js:34:14)
      at Object.obj.<computed> [as get] (node_modules/supertest/index.js:43:18)
      at __tests__/controllers/partnumbers.test.ts:43:40
      at __tests__/controllers/partnumbers.test.ts:8:71
      at Object.<anonymous>.__awaiter (__tests__/controllers/partnumbers.test.ts:4:12)
      at Object.<anonymous> (__tests__/controllers/partnumbers.test.ts:42:67)

I couldn't find anything online or in the github related to a 'Timeout' open handle.

I traced the issue to a rate limiting middleware I had made.

const rateLimiter = (req: Request, res: Response, next: NextFunction) => {
	// Get the client's IP address
	const clientIp = req.ip;

	// Check if the client has exceeded the rate limit
	if (requestCounter.has(clientIp)) {
		const requestsMade = requestCounter.get(clientIp);
		if (requestsMade >= REQUESTS_PER_MINUTE) {
			return res.status(429).send("Too Many Requests");
		}
	}

	// Increment the number of requests made by this client
	requestCounter.set(clientIp, (requestCounter.get(clientIp) || 0) + 1);

	// Clear the request count for this client after 1 minute
	const requestTimer = setTimeout(() => {
		requestCounter.delete(clientIp);
		clearInterval(refillTimer); // clear the refill timer, which also prevents unopen handles in tests
	}, 60 * 1000);

	// Refill the bucket by 1 request every second
	const refillTimer = setInterval(() => {
		requestCounter.set(clientIp, Math.max(requestCounter.get(clientIp) - 1, 0));
	}, 1000);

	// Call the next middleware in the chain
	next();

	// Clean up the timers after the middleware has finished
	clearTimeout(requestTimer);
	clearInterval(refillTimer);
};

Without the clearTimeout and clearInterval calls the timers will start running indefinitely, even after the tests have completed, which was leading to the open handle error.

After adding the calls to clear these two timers I no longer experience the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant