@@ -25,7 +25,9 @@ type MethodWrapperOptions = {
25
25
} ;
26
26
27
27
// eslint-disable-next-line @typescript-eslint/no-explicit-any
28
- function wrapMethodWithSentry < T extends ( ...args : any [ ] ) => any > (
28
+ type OriginalMethod = ( ...args : any [ ] ) => any ;
29
+
30
+ function wrapMethodWithSentry < T extends OriginalMethod > (
29
31
wrapperOptions : MethodWrapperOptions ,
30
32
handler : T ,
31
33
callback ?: ( ...args : Parameters < T > ) => void ,
@@ -221,8 +223,61 @@ export function instrumentDurableObjectWithSentry<
221
223
) ;
222
224
}
223
225
}
226
+ const instrumentedPrototype = instrumentPrototype ( target , options , context ) ;
227
+ Object . setPrototypeOf ( obj , instrumentedPrototype ) ;
224
228
225
229
return obj ;
226
230
} ,
227
231
} ) ;
228
232
}
233
+
234
+ function instrumentPrototype < T extends NewableFunction > (
235
+ target : T ,
236
+ options : CloudflareOptions ,
237
+ context : MethodWrapperOptions [ 'context' ] ,
238
+ ) : typeof target . prototype {
239
+ const sentryMethods = new Map < string | symbol , OriginalMethod > ( ) ;
240
+ let proto = target . prototype ;
241
+ const instrumentedPrototype = new Proxy ( proto , {
242
+ get ( target , prop , receiver ) {
243
+ if ( sentryMethods . has ( prop ) ) {
244
+ return sentryMethods . get ( prop ) ;
245
+ }
246
+ return Reflect . get ( target , prop , receiver ) ;
247
+ } ,
248
+ } ) ;
249
+ while ( proto && proto !== Object . prototype ) {
250
+ for ( const method of Object . getOwnPropertyNames ( proto ) ) {
251
+ if ( method === 'constructor' || sentryMethods . has ( method ) ) {
252
+ continue ;
253
+ }
254
+
255
+ const value = Reflect . get ( proto , method , proto ) ;
256
+ if ( typeof value === 'function' ) {
257
+ sentryMethods . set (
258
+ method ,
259
+ wrapMethodWithSentry (
260
+ {
261
+ options,
262
+ context,
263
+ spanName : method ,
264
+ spanOp : 'rpc' ,
265
+ } ,
266
+ // <editor-fold desc="Disable __SENTRY_INSTRUMENTED__ for prototype methods">
267
+ new Proxy ( value , {
268
+ set ( target , p , newValue , receiver ) : boolean {
269
+ if ( '__SENTRY_INSTRUMENTED__' === p ) {
270
+ return true ;
271
+ }
272
+ return Reflect . set ( target , p , newValue , receiver ) ;
273
+ } ,
274
+ } ) ,
275
+ // </editor-fold>
276
+ ) ,
277
+ ) ;
278
+ }
279
+ }
280
+ proto = Object . getPrototypeOf ( proto ) ;
281
+ }
282
+ return instrumentedPrototype ;
283
+ }
0 commit comments