Skip to content

Commit 4de913e

Browse files
authored
Merge pull request #14 from shenald-dev/jules-bolt-array-validation-and-cache-bound-6403325572547754351
Improve array validation and bound computationCache memory map size
2 parents 919aa37 + c5cc186 commit 4de913e

4 files changed

Lines changed: 29 additions & 4 deletions

File tree

.jules/bolt.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,11 @@ The default Express `express.json()` middleware limits incoming JSON payloads to
1212

1313
Action:
1414
Increased the JSON payload limit in `src/index.js` to 10mb, and added an explicit error handler to intercept `err.type === 'entity.too.large'` and return a standardized `413 Payload Too Large` JSON response.
15+
16+
## 2024-05-24 — Improve array validation and bound computationCache memory map size
17+
18+
Learning:
19+
Unbounded Map caches in repeated serverless or long-running operations can cause memory leaks. Also, `req.body.messages` without `Array.isArray()` validation can lead to crashes if a string is provided and later mapped.
20+
21+
Action:
22+
Added strict `!Array.isArray(messages)` validation to the `/v1/chat/completions` API route, and restricted the `computationCache` Map size to 1000 items in `src/index.js` to ensure long-term stability and resilience.

src/index.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ app.use((err, req, res, next) => {
3737
// API endpoints
3838
app.post('/v1/chat/completions', (req, res) => {
3939
const { model, messages } = req.body || {};
40-
if (!model || !messages) {
41-
return res.status(400).json({ error: 'Missing model or messages' });
40+
if (!model || !messages || !Array.isArray(messages)) {
41+
return res.status(400).json({ error: 'Missing or invalid model or messages' });
4242
}
4343

4444
// Mock unified response
@@ -91,6 +91,11 @@ function heavyComputation(iterations) {
9191
return computationCache.get(iterations);
9292
}
9393

94+
// Prevent memory leak from unbounded cache growth
95+
if (computationCache.size >= 1000) {
96+
computationCache.clear();
97+
}
98+
9499
let sum = 0;
95100
for (let i = 0; i < iterations; i++) {
96101
sum += Math.sqrt(i) * Math.sin(i * 0.01);

tests/api.test.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,19 @@ test('POST /v1/chat/completions fails without model', async () => {
3333
});
3434

3535
assert.strictEqual(res.status, 400);
36-
assert.strictEqual(res.body.error, 'Missing model or messages');
36+
assert.strictEqual(res.body.error, 'Missing or invalid model or messages');
37+
});
38+
39+
test('POST /v1/chat/completions fails when messages is not an array', async () => {
40+
const res = await request(app)
41+
.post('/v1/chat/completions')
42+
.send({
43+
model: 'gpt-4',
44+
messages: "Hello!"
45+
});
46+
47+
assert.strictEqual(res.status, 400);
48+
assert.strictEqual(res.body.error, 'Missing or invalid model or messages');
3749
});
3850

3951
test('POST /v1/chat/completions fails with invalid JSON gracefully', async () => {

tests/api_robustness.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ test('POST /v1/chat/completions handles undefined req.body (e.g. non-JSON conten
1010
.send('some text');
1111

1212
assert.strictEqual(res.status, 400);
13-
assert.strictEqual(res.body.error, 'Missing model or messages');
13+
assert.strictEqual(res.body.error, 'Missing or invalid model or messages');
1414
});
1515

1616
test('POST /v1/chat/completions handles payload too large gracefully', async () => {

0 commit comments

Comments
 (0)