@@ -4,7 +4,8 @@ import type { Span as OtelSpan, SpanProcessor as OtelSpanProcessor } from '@open
4
4
import { addGlobalEventProcessor , getCurrentHub } from '@sentry/core' ;
5
5
import { Transaction } from '@sentry/tracing' ;
6
6
import type { DynamicSamplingContext , Span as SentrySpan , TraceparentData , TransactionContext } from '@sentry/types' ;
7
- import { logger } from '@sentry/utils' ;
7
+ import { logger , isString } from '@sentry/utils' ;
8
+ import { SemanticAttributes } from '@opentelemetry/semantic-conventions' ;
8
9
9
10
import { SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY , SENTRY_TRACE_PARENT_CONTEXT_KEY } from './constants' ;
10
11
import { isSentryRequestSpan } from './utils/is-sentry-request' ;
@@ -93,6 +94,12 @@ export class SentrySpanProcessor implements OtelSpanProcessor {
93
94
* @inheritDoc
94
95
*/
95
96
public onEnd ( otelSpan : OtelSpan ) : void {
97
+ const hub = getCurrentHub ( ) ;
98
+ if ( ! hub ) {
99
+ __DEBUG_BUILD__ && logger . error ( 'SentrySpanProcessor has triggered onEnd before a hub has been setup.' ) ;
100
+ return ;
101
+ }
102
+
96
103
const otelSpanId = otelSpan . spanContext ( ) . spanId ;
97
104
const sentrySpan = SENTRY_SPAN_PROCESSOR_MAP . get ( otelSpanId ) ;
98
105
@@ -112,6 +119,45 @@ export class SentrySpanProcessor implements OtelSpanProcessor {
112
119
return ;
113
120
}
114
121
122
+ otelSpan . events . forEach ( event => {
123
+ if ( event . name !== 'exception' ) {
124
+ return ;
125
+ }
126
+
127
+ const attributes = event . attributes ;
128
+ if ( ! attributes ) {
129
+ return ;
130
+ }
131
+
132
+ const message = attributes [ SemanticAttributes . EXCEPTION_MESSAGE ] ;
133
+ if ( ! isString ( message ) ) {
134
+ return ;
135
+ }
136
+ const syntheticError = new Error ( message ) ;
137
+
138
+ const stack = attributes [ SemanticAttributes . EXCEPTION_STACKTRACE ] ;
139
+ if ( isString ( stack ) ) {
140
+ syntheticError . stack = stack ;
141
+ }
142
+
143
+ const type = attributes [ SemanticAttributes . EXCEPTION_TYPE ] ;
144
+ if ( isString ( type ) ) {
145
+ syntheticError . name = type ;
146
+ }
147
+
148
+ hub . captureException ( syntheticError , {
149
+ captureContext : {
150
+ contexts : {
151
+ trace : {
152
+ trace_id : otelSpan . spanContext ( ) . traceId ,
153
+ span_id : otelSpan . spanContext ( ) . spanId ,
154
+ parent_span_id : otelSpan . parentSpanId ,
155
+ } ,
156
+ } ,
157
+ } ,
158
+ } ) ;
159
+ } ) ;
160
+
115
161
if ( sentrySpan instanceof Transaction ) {
116
162
updateTransactionWithOtelData ( sentrySpan , otelSpan ) ;
117
163
} else {
0 commit comments