Skip to content

Commit 4eac4a4

Browse files
committed
fix: return json rate limit errors
1 parent a4df48b commit 4eac4a4

2 files changed

Lines changed: 43 additions & 1 deletion

File tree

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import rateLimit from "express-rate-limit";
2+
import { fail } from "../utils/response.js";
23

34
export const apiLimiter = rateLimit({
45
windowMs: 15 * 60 * 1000,
56
limit: 200,
67
standardHeaders: "draft-7",
7-
legacyHeaders: false
8+
legacyHeaders: false,
9+
handler: (req, res) => fail(res, "Too many requests", 429)
810
});
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import test from "node:test";
2+
import assert from "node:assert/strict";
3+
import { createApp } from "../app.js";
4+
5+
async function withServer(run) {
6+
const app = createApp();
7+
const server = app.listen(0);
8+
9+
await new Promise((resolve, reject) => {
10+
server.once("listening", resolve);
11+
server.once("error", reject);
12+
});
13+
14+
try {
15+
const { port } = server.address();
16+
await run(`http://127.0.0.1:${port}`);
17+
} finally {
18+
await new Promise((resolve, reject) => {
19+
server.close((error) => (error ? reject(error) : resolve()));
20+
});
21+
}
22+
}
23+
24+
test("API rate limiter returns JSON failure envelope", async () => {
25+
await withServer(async (baseUrl) => {
26+
let response;
27+
for (let i = 0; i < 201; i += 1) {
28+
response = await fetch(`${baseUrl}/api/users`);
29+
}
30+
31+
const payload = await response.json();
32+
33+
assert.equal(response.status, 429);
34+
assert.match(response.headers.get("content-type"), /application\/json/);
35+
assert.deepEqual(payload, {
36+
success: false,
37+
message: "Too many requests",
38+
});
39+
});
40+
});

0 commit comments

Comments
 (0)