@@ -34,14 +34,14 @@ export function trace<T>(
34
34
35
35
const parentSpan = scope . getSpan ( ) ;
36
36
37
- function startActiveSpan ( ) : Span | undefined {
37
+ function getChildSpanOrTransaction ( ) : Span | undefined {
38
38
if ( ! hasTracingEnabled ( ) ) {
39
39
return undefined ;
40
40
}
41
41
return parentSpan ? parentSpan . startChild ( ctx ) : hub . startTransaction ( ctx ) ;
42
42
}
43
43
44
- const activeSpan = startActiveSpan ( ) ;
44
+ const activeSpan = getChildSpanOrTransaction ( ) ;
45
45
scope . setSpan ( activeSpan ) ;
46
46
47
47
function finishAndSetSpan ( ) : void {
@@ -100,14 +100,14 @@ export function startActiveSpan<T>(context: TransactionContext, callback: (span:
100
100
101
101
const parentSpan = scope . getSpan ( ) ;
102
102
103
- function startActiveSpan ( ) : Span | undefined {
103
+ function getChildSpanOrTransaction ( ) : Span | undefined {
104
104
if ( ! hasTracingEnabled ( ) ) {
105
105
return undefined ;
106
106
}
107
107
return parentSpan ? parentSpan . startChild ( ctx ) : hub . startTransaction ( ctx ) ;
108
108
}
109
109
110
- const activeSpan = startActiveSpan ( ) ;
110
+ const activeSpan = getChildSpanOrTransaction ( ) ;
111
111
scope . setSpan ( activeSpan ) ;
112
112
113
113
function finishAndSetSpan ( ) : void {
@@ -141,6 +141,56 @@ export function startActiveSpan<T>(context: TransactionContext, callback: (span:
141
141
return maybePromiseResult ;
142
142
}
143
143
144
+ /**
145
+ * Similar to `Sentry.startActiveSpan`. Wraps a function with a transaction/span, but does not finish the span
146
+ * after the function is done automatically.
147
+ *
148
+ * The created span is the active span and will be used as parent by other spans created inside the function
149
+ * and can be accessed via `Sentry.getSpan()`, as long as the function is executed while the scope is active.
150
+ *
151
+ * Note that if you have not enabled tracing extensions via `addTracingExtensions`
152
+ * or you didn't set `tracesSampleRate`, this function will not generate spans
153
+ * and the `span` returned from the callback will be undefined.
154
+ */
155
+ export function startActiveSpanManual < T > ( context : TransactionContext , callback : ( span : Span | undefined ) => T ) : T {
156
+ const ctx = { ...context } ;
157
+ // If a name is set and a description is not, set the description to the name.
158
+ if ( ctx . name !== undefined && ctx . description === undefined ) {
159
+ ctx . description = ctx . name ;
160
+ }
161
+
162
+ const hub = getCurrentHub ( ) ;
163
+ const scope = hub . getScope ( ) ;
164
+
165
+ const parentSpan = scope . getSpan ( ) ;
166
+
167
+ function getChildSpanOrTransaction ( ) : Span | undefined {
168
+ if ( ! hasTracingEnabled ( ) ) {
169
+ return undefined ;
170
+ }
171
+ return parentSpan ? parentSpan . startChild ( ctx ) : hub . startTransaction ( ctx ) ;
172
+ }
173
+
174
+ const activeSpan = getChildSpanOrTransaction ( ) ;
175
+ scope . setSpan ( activeSpan ) ;
176
+
177
+ let maybePromiseResult : T ;
178
+ try {
179
+ maybePromiseResult = callback ( activeSpan ) ;
180
+ } catch ( e ) {
181
+ activeSpan && activeSpan . setStatus ( 'internal_error' ) ;
182
+ throw e ;
183
+ }
184
+
185
+ if ( isThenable ( maybePromiseResult ) ) {
186
+ Promise . resolve ( maybePromiseResult ) . then ( undefined , ( ) => {
187
+ activeSpan && activeSpan . setStatus ( 'internal_error' ) ;
188
+ } ) ;
189
+ }
190
+
191
+ return maybePromiseResult ;
192
+ }
193
+
144
194
/**
145
195
* Creates a span. This span is not set as active, so will not get automatic instrumentation spans
146
196
* as children or be able to be accessed via `Sentry.getSpan()`.
0 commit comments