Skip to content

Commit 8a5104c

Browse files
committed
fixup! fix(cloudflare): Skip SDK initialization for OPTIONS/HEAD requests
1 parent 6424081 commit 8a5104c

2 files changed

Lines changed: 68 additions & 0 deletions

File tree

packages/cloudflare/src/request.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,20 @@ export function wrapRequestHandler(
8585
}
8686
}
8787

88+
// Do not capture spans for OPTIONS and HEAD requests
89+
if (request.method === 'OPTIONS' || request.method === 'HEAD') {
90+
try {
91+
return await handler();
92+
} catch (e) {
93+
if (captureErrors) {
94+
captureException(e, { mechanism: { handled: false, type: 'auto.http.cloudflare' } });
95+
}
96+
throw e;
97+
} finally {
98+
waitUntil?.(flushAndDispose(client));
99+
}
100+
}
101+
88102
if (client) {
89103
await captureIncomingRequestBody(client, request);
90104
}

packages/cloudflare/test/request.test.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,60 @@ describe('flushAndDispose', () => {
563563
disposeSpy.mockRestore();
564564
});
565565

566+
test('dispose is called for OPTIONS requests', async () => {
567+
const context = createMockExecutionContext();
568+
const waits: Promise<unknown>[] = [];
569+
const waitUntil = vi.fn(promise => waits.push(promise));
570+
(context as any).waitUntil = waitUntil;
571+
572+
const disposeSpy = vi.spyOn(CloudflareClient.prototype, 'dispose');
573+
const flushSpy = vi.spyOn(SentryCore.Client.prototype, 'flush').mockResolvedValue(true);
574+
575+
await wrapRequestHandler(
576+
{
577+
options: MOCK_OPTIONS,
578+
request: new Request('https://example.com', { method: 'OPTIONS' }),
579+
context,
580+
},
581+
() => new Response('', { status: 200 }),
582+
);
583+
584+
// Wait for all waitUntil promises to resolve
585+
await Promise.all(waits);
586+
587+
expect(disposeSpy).toHaveBeenCalled();
588+
589+
flushSpy.mockRestore();
590+
disposeSpy.mockRestore();
591+
});
592+
593+
test('dispose is called for HEAD requests', async () => {
594+
const context = createMockExecutionContext();
595+
const waits: Promise<unknown>[] = [];
596+
const waitUntil = vi.fn(promise => waits.push(promise));
597+
(context as any).waitUntil = waitUntil;
598+
599+
const disposeSpy = vi.spyOn(CloudflareClient.prototype, 'dispose');
600+
const flushSpy = vi.spyOn(SentryCore.Client.prototype, 'flush').mockResolvedValue(true);
601+
602+
await wrapRequestHandler(
603+
{
604+
options: MOCK_OPTIONS,
605+
request: new Request('https://example.com', { method: 'HEAD' }),
606+
context,
607+
},
608+
() => new Response('', { status: 200 }),
609+
);
610+
611+
// Wait for all waitUntil promises to resolve
612+
await Promise.all(waits);
613+
614+
expect(disposeSpy).toHaveBeenCalled();
615+
616+
flushSpy.mockRestore();
617+
disposeSpy.mockRestore();
618+
});
619+
566620
test('dispose is called after streaming response completes', async () => {
567621
const context = createMockExecutionContext();
568622
const waits: Promise<unknown>[] = [];

0 commit comments

Comments
 (0)