Skip to content

Commit 56e336b

Browse files
test(web): cover unhandled-rejection suppression in readiness probe
New test attaches a process-level 'unhandledRejection' listener and asserts that the readiness probe does not surface the check promise's rejection to it, even when the race has already returned the timeout error. Locks in the no-op `.catch` in `withTimeout`.
1 parent 7a4ddc5 commit 56e336b

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

‎packages/web/src/app/api/(server)/health/ready/route.test.ts‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,37 @@ describe('GET /api/health/ready', () => {
149149
// Generous upper bound to avoid flakes; serial would be ~3x delay.
150150
expect(elapsed).toBeLessThan(delay * 2.5);
151151
});
152+
153+
test('does not surface check rejections as unhandled promise rejections', async () => {
154+
// The check rejects synchronously (well within the 2s timeout). The
155+
// no-op `.catch` attached in `withTimeout` must absorb that
156+
// rejection so the Node process does not log an
157+
// unhandled-promise-rejection warning while the readiness request
158+
// has already moved on.
159+
const checkRejection = new Error('check rejected');
160+
const unhandled: unknown[] = [];
161+
const onUnhandled = (err: unknown) => { unhandled.push(err); };
162+
process.on('unhandledRejection', onUnhandled);
163+
164+
try {
165+
mocks.unsafePrisma.$queryRaw.mockRejectedValue(checkRejection);
166+
mocks.redisPing.mockResolvedValue('PONG');
167+
mocks.zoektList.mockImplementation(
168+
(_request: unknown, callback: (err: Error | null) => void) => {
169+
callback(null);
170+
},
171+
);
172+
173+
const response = await GET();
174+
const body = await response.json();
175+
176+
expect(response.status).toBe(503);
177+
expect(body.checks.postgres.status).toBe('error');
178+
// Give the rejection microtask a chance to fire and propagate.
179+
await new Promise((resolve) => setTimeout(resolve, 50));
180+
expect(unhandled).not.toContain(checkRejection);
181+
} finally {
182+
process.off('unhandledRejection', onUnhandled);
183+
}
184+
});
152185
});

0 commit comments

Comments
 (0)