@@ -110,8 +110,7 @@ function wrapMethodWithSentry<T extends OriginalMethod>(
110110 }
111111 : { } ;
112112
113- // Only create these spans if they have a parent span.
114- return startSpan ( { name : wrapperOptions . spanName , attributes, onlyIfParent : true } , ( ) => {
113+ return startSpan ( { name : wrapperOptions . spanName , attributes } , ( ) => {
115114 try {
116115 const result = Reflect . apply ( target , thisArg , args ) ;
117116
@@ -273,46 +272,87 @@ export function instrumentDurableObjectWithSentry<
273272 ) ;
274273 }
275274 }
276- const instrumentedPrototype = instrumentPrototype ( target , options , context ) ;
277- Object . setPrototypeOf ( obj , instrumentedPrototype ) ;
275+
276+ // Store context and options on the instance for prototype methods to access
277+ Object . defineProperty ( obj , '__SENTRY_CONTEXT__' , {
278+ value : context ,
279+ enumerable : false ,
280+ writable : false ,
281+ configurable : false ,
282+ } ) ;
283+
284+ Object . defineProperty ( obj , '__SENTRY_OPTIONS__' , {
285+ value : options ,
286+ enumerable : false ,
287+ writable : false ,
288+ configurable : false ,
289+ } ) ;
290+
291+ instrumentPrototype ( target ) ;
278292
279293 return obj ;
280294 } ,
281295 } ) ;
282296}
283297
284- function instrumentPrototype < T extends NewableFunction > (
285- target : T ,
286- options : CloudflareOptions ,
287- context : MethodWrapperOptions [ 'context' ] ,
288- ) : T {
289- return new Proxy ( target . prototype , {
290- get ( target , prop , receiver ) {
291- const value = Reflect . get ( target , prop , receiver ) ;
292- if ( prop === 'constructor' || typeof value !== 'function' ) {
293- return value ;
298+ function instrumentPrototype < T extends NewableFunction > ( target : T ) : void {
299+ const proto = target . prototype ;
300+
301+ // Get all methods from the prototype chain
302+ const methodNames = new Set < string > ( ) ;
303+ let current = proto ;
304+
305+ while ( current && current !== Object . prototype ) {
306+ Object . getOwnPropertyNames ( current ) . forEach ( name => {
307+ if ( name !== 'constructor' && typeof current [ name ] === 'function' ) {
308+ methodNames . add ( name ) ;
309+ }
310+ } ) ;
311+ current = Object . getPrototypeOf ( current ) ;
312+ }
313+
314+ // Instrument each method on the prototype
315+ methodNames . forEach ( methodName => {
316+ const originalMethod = proto [ methodName ] ;
317+
318+ if ( ! originalMethod || isInstrumented ( originalMethod ) ) {
319+ return ;
320+ }
321+
322+ // Create a wrapper that gets context/options from the instance at runtime
323+ const wrappedMethod = function ( this : any , ...args : any [ ] ) {
324+ const instanceContext = this . __SENTRY_CONTEXT__ ;
325+ const instanceOptions = this . __SENTRY_OPTIONS__ ;
326+
327+ if ( ! instanceOptions ) {
328+ // Fallback to original method if no Sentry data found
329+ return originalMethod . apply ( this , args ) ;
294330 }
295- const wrapped = wrapMethodWithSentry (
296- { options, context, spanName : prop . toString ( ) , spanOp : 'rpc' } ,
297- value ,
331+
332+ // Use the existing wrapper but with instance-specific context/options
333+ const wrapper = wrapMethodWithSentry (
334+ {
335+ options : instanceOptions ,
336+ context : instanceContext ,
337+ spanName : methodName ,
338+ spanOp : 'rpc' ,
339+ } ,
340+ originalMethod ,
298341 undefined ,
299- true ,
342+ true , // noMark = true since we'll mark the prototype method
300343 ) ;
301- const instrumented = new Proxy ( wrapped , {
302- get ( target , p , receiver ) {
303- if ( '__SENTRY_INSTRUMENTED__' === p ) {
304- return true ;
305- }
306- return Reflect . get ( target , p , receiver ) ;
307- } ,
308- } ) ;
309- Object . defineProperty ( receiver , prop , {
310- value : instrumented ,
311- enumerable : true ,
312- writable : true ,
313- configurable : true ,
314- } ) ;
315- return instrumented ;
316- } ,
344+
345+ return wrapper . apply ( this , args ) ;
346+ } ;
347+
348+ markAsInstrumented ( wrappedMethod ) ;
349+
350+ // Replace the prototype method
351+ Object . defineProperty ( proto , methodName , {
352+ value : wrappedMethod ,
353+ enumerable : false ,
354+ writable : true ,
355+ configurable : true ,
356+ } ) ;
317357 } ) ;
318358}
0 commit comments