@@ -8,6 +8,7 @@ import { beforeAll, beforeEach, describe, expect, onTestFinished, test, vi } fro
88import { setAsyncLocalStorageAsyncContextStrategy } from '../src/async' ;
99import type { CloudflareOptions } from '../src/client' ;
1010import { CloudflareClient } from '../src/client' ;
11+ import { httpServerIntegration } from '../src/integrations/httpServer' ;
1112import { wrapRequestHandler } from '../src/request' ;
1213
1314const MOCK_OPTIONS : CloudflareOptions = {
@@ -206,18 +207,14 @@ describe('withSentry', () => {
206207 expect ( sentryEvent . contexts ?. culture ) . toEqual ( { timezone : 'UTC' } ) ;
207208 } ) ;
208209
209- // TODO(v11): Body capture should be gated on `dataCollection.httpBodies` (only capture when
210- // `'incomingRequest'` is listed). Until then we keep the historical behavior of capturing
211- // incoming request bodies by default at `'medium'`, consistent with the Node SDK.
212- test ( 'captures request body with default integration (medium size)' , async ( ) => {
210+ test ( 'captures request body by default (all body types included by default)' , async ( ) => {
213211 let sentryEvent : Event = { } ;
214212 const context = createMockExecutionContext ( ) ;
215213
216214 await wrapRequestHandler (
217215 {
218216 options : {
219217 ...MOCK_OPTIONS ,
220- // Default integrations include httpServerIntegration with 'medium' default
221218 beforeSend ( event ) {
222219 sentryEvent = event ;
223220 return null ;
@@ -241,6 +238,67 @@ describe('withSentry', () => {
241238 ) ;
242239 } ) ;
243240
241+ test ( 'does not capture request body when dataCollection.httpBodies excludes incomingRequest' , async ( ) => {
242+ let sentryEvent : Event = { } ;
243+ const context = createMockExecutionContext ( ) ;
244+
245+ await wrapRequestHandler (
246+ {
247+ options : {
248+ ...MOCK_OPTIONS ,
249+ dataCollection : { httpBodies : [ ] } ,
250+ beforeSend ( event ) {
251+ sentryEvent = event ;
252+ return null ;
253+ } ,
254+ } ,
255+ request : new Request ( 'https://example.com' , {
256+ method : 'POST' ,
257+ headers : { 'content-type' : 'application/json' } ,
258+ body : JSON . stringify ( { username : 'test' , data : 'value' } ) ,
259+ } ) ,
260+ context,
261+ } ,
262+ ( ) => {
263+ SentryCore . captureMessage ( 'request body' ) ;
264+ return new Response ( 'test' ) ;
265+ } ,
266+ ) ;
267+
268+ expect ( sentryEvent . sdkProcessingMetadata ?. normalizedRequest ?. data ) . toBeUndefined ( ) ;
269+ } ) ;
270+
271+ test ( 'explicit maxRequestBodySize overrides dataCollection.httpBodies' , async ( ) => {
272+ let sentryEvent : Event = { } ;
273+ const context = createMockExecutionContext ( ) ;
274+
275+ await wrapRequestHandler (
276+ {
277+ options : {
278+ ...MOCK_OPTIONS ,
279+ dataCollection : { httpBodies : [ ] } ,
280+ integrations : [ httpServerIntegration ( { maxRequestBodySize : 'medium' } ) ] ,
281+ beforeSend ( event ) {
282+ sentryEvent = event ;
283+ return null ;
284+ } ,
285+ } ,
286+ request : new Request ( 'https://example.com' , {
287+ method : 'POST' ,
288+ headers : { 'content-type' : 'application/json' } ,
289+ body : JSON . stringify ( { key : 'value' } ) ,
290+ } ) ,
291+ context,
292+ } ,
293+ ( ) => {
294+ SentryCore . captureMessage ( 'request body' ) ;
295+ return new Response ( 'test' ) ;
296+ } ,
297+ ) ;
298+
299+ expect ( sentryEvent . sdkProcessingMetadata ?. normalizedRequest ?. data ) . toEqual ( JSON . stringify ( { key : 'value' } ) ) ;
300+ } ) ;
301+
244302 // TODO(v11): Cookies should be attached (subject to denylist filtering) by default. Until then we keep the
245303 // historical Cloudflare behavior of not attaching cookies unless the user explicitly opts in.
246304 test ( 'does not capture cookies by default' , async ( ) => {
0 commit comments