1- import { captureException } from '@sentry/core' ;
2- import { addExceptionMechanism } from '@sentry/utils' ;
1+ import { captureException , configureScope , runWithAsyncContext } from '@sentry/core' ;
2+ import { addExceptionMechanism , extractTraceparentData } from '@sentry/utils' ;
33
44interface FunctionComponent {
55 ( ...args : unknown [ ] ) : unknown ;
66}
77
88interface ClassComponent {
99 new ( ...args : unknown [ ] ) : {
10+ props ?: unknown ;
1011 render ( ...args : unknown [ ] ) : unknown ;
1112 } ;
1213}
@@ -23,41 +24,76 @@ export function wrapPageComponentWithSentry(pageComponent: FunctionComponent | C
2324 if ( isReactClassComponent ( pageComponent ) ) {
2425 return class SentryWrappedPageComponent extends pageComponent {
2526 public render ( ...args : unknown [ ] ) : unknown {
26- try {
27- return super . render ( ... args ) ;
28- } catch ( e ) {
29- captureException ( e , scope => {
30- scope . addEventProcessor ( event => {
31- addExceptionMechanism ( event , {
32- handled : false ,
33- } ) ;
34- return event ;
35- } ) ;
27+ return runWithAsyncContext ( ( ) => {
28+ configureScope ( scope => {
29+ // We extract the sentry trace data that is put in the component props by datafetcher wrappers
30+ const sentryTraceData =
31+ typeof this . props === 'object' &&
32+ this . props !== null &&
33+ '_sentryTraceData' in this . props &&
34+ typeof this . props . _sentryTraceData === 'string'
35+ ? this . props . _sentryTraceData
36+ : undefined ;
3637
37- return scope ;
38+ if ( sentryTraceData ) {
39+ const traceparentData = extractTraceparentData ( sentryTraceData ) ;
40+ scope . setContext ( 'trace' , {
41+ span_id : traceparentData ?. parentSpanId ,
42+ trace_id : traceparentData ?. traceId ,
43+ } ) ;
44+ }
3845 } ) ;
39- throw e ;
40- }
46+
47+ try {
48+ return super . render ( ...args ) ;
49+ } catch ( e ) {
50+ captureException ( e , scope => {
51+ scope . addEventProcessor ( event => {
52+ addExceptionMechanism ( event , {
53+ handled : false ,
54+ } ) ;
55+ return event ;
56+ } ) ;
57+
58+ return scope ;
59+ } ) ;
60+ throw e ;
61+ }
62+ } ) ;
4163 }
4264 } ;
4365 } else if ( typeof pageComponent === 'function' ) {
4466 return new Proxy ( pageComponent , {
45- apply ( target , thisArg , argArray ) {
46- try {
47- return target . apply ( thisArg , argArray ) ;
48- } catch ( e ) {
49- captureException ( e , scope => {
50- scope . addEventProcessor ( event => {
51- addExceptionMechanism ( event , {
52- handled : false ,
53- } ) ;
54- return event ;
55- } ) ;
67+ apply ( target , thisArg , argArray : [ { _sentryTraceData ?: string } | undefined ] ) {
68+ return runWithAsyncContext ( ( ) => {
69+ configureScope ( scope => {
70+ // We extract the sentry trace data that is put in the component props by datafetcher wrappers
71+ const sentryTraceData = argArray ?. [ 0 ] ?. _sentryTraceData ;
5672
57- return scope ;
73+ if ( sentryTraceData ) {
74+ const traceparentData = extractTraceparentData ( sentryTraceData ) ;
75+ scope . setContext ( 'trace' , {
76+ span_id : traceparentData ?. parentSpanId ,
77+ trace_id : traceparentData ?. traceId ,
78+ } ) ;
79+ }
5880 } ) ;
59- throw e ;
60- }
81+ try {
82+ return target . apply ( thisArg , argArray ) ;
83+ } catch ( e ) {
84+ captureException ( e , scope => {
85+ scope . addEventProcessor ( event => {
86+ addExceptionMechanism ( event , {
87+ handled : false ,
88+ } ) ;
89+ return event ;
90+ } ) ;
91+
92+ return scope ;
93+ } ) ;
94+ throw e ;
95+ }
96+ } ) ;
6197 } ,
6298 } ) ;
6399 } else {
0 commit comments