Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,11 @@ Learning:
The API gateway was generating pseudo-random mock response IDs using `Math.random().toString(36).substr(2, 9)`. This approach is both slow under heavy load and fundamentally flawed for a large-scale system due to the high risk of ID collisions (non-cryptographic randomness, short string length).

Action:
Switched to Node.js's native `crypto.randomUUID()` to generate mock response IDs. This provides mathematically guaranteed uniqueness (crucial for a unified API gateway) and is natively faster than the previous string manipulation approach. Tests were updated to reflect the increased length of UUIDs over the previous 9-character pseudo-random strings.
Switched to Node.js's native `crypto.randomUUID()` to generate mock response IDs. This provides mathematically guaranteed uniqueness (crucial for a unified API gateway) and is natively faster than the previous string manipulation approach. Tests were updated to reflect the increased length of UUIDs over the previous 9-character pseudo-random strings.
## 2026-03-18 — Handle Invalid JSON Gracefully

Learning:
Express.js default `express.json()` middleware can leak server stack traces via HTML responses when it encounters malformed JSON input, which degrades API reliability and can expose internal structure.

Action:
Added a custom error handling middleware immediately after `express.json()` to catch `SyntaxError` with status 400 and return a clean, standard JSON `400 Bad Request` payload instead of an HTML stack trace.
8 changes: 8 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ app.use(helmet());
app.use(cors());
app.use(express.json());

// Handle invalid JSON gracefully
app.use((err, req, res, next) => {
if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
return res.status(400).json({ error: 'Invalid JSON payload' });
}
next(err);
});

// API endpoints
app.post('/v1/chat/completions', (req, res) => {
const { model, messages } = req.body;
Expand Down
10 changes: 10 additions & 0 deletions tests/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,13 @@ test('POST /v1/chat/completions fails without model', async () => {
assert.strictEqual(res.status, 400);
assert.strictEqual(res.body.error, 'Missing model or messages');
});

test('POST /v1/chat/completions fails with invalid JSON gracefully', async () => {
const res = await request(app)
.post('/v1/chat/completions')
.set('Content-Type', 'application/json')
.send('{invalid_json');

assert.strictEqual(res.status, 400);
assert.strictEqual(res.body.error, 'Invalid JSON payload');
});
Loading