|
6 | 6 | handleCallbackErrors,
|
7 | 7 | runWithAsyncContext,
|
8 | 8 | startSpan,
|
| 9 | + withScope, |
9 | 10 | } from '@sentry/core';
|
10 | 11 | import { logger, tracingContextFromHeaders } from '@sentry/utils';
|
11 | 12 |
|
@@ -84,47 +85,48 @@ async function withServerActionInstrumentationImplementation<A extends (...args:
|
84 | 85 |
|
85 | 86 | let res;
|
86 | 87 | try {
|
87 |
| - res = await startSpan( |
88 |
| - { |
89 |
| - op: 'function.server_action', |
90 |
| - name: `serverAction/${serverActionName}`, |
91 |
| - status: 'ok', |
92 |
| - ...traceparentData, |
93 |
| - metadata: { |
94 |
| - source: 'route', |
95 |
| - dynamicSamplingContext: traceparentData && !dynamicSamplingContext ? {} : dynamicSamplingContext, |
96 |
| - request: { |
97 |
| - headers: fullHeadersObject, |
98 |
| - }, |
99 |
| - }, |
100 |
| - }, |
101 |
| - async span => { |
102 |
| - const result = await handleCallbackErrors(callback, error => { |
103 |
| - captureException(error, { mechanism: { handled: false } }); |
| 88 | + res = await withScope(scope => { |
| 89 | + if (options.formData) { |
| 90 | + const formDataObject: Record<string, unknown> = {}; |
| 91 | + options.formData.forEach((value, key) => { |
| 92 | + if (typeof value === 'string') { |
| 93 | + formDataObject[key] = value; |
| 94 | + } else { |
| 95 | + formDataObject[key] = '[non-string value]'; |
| 96 | + } |
104 | 97 | });
|
| 98 | + // Since formDataObject is not a primitive, we cannot store it on the span as attributes |
| 99 | + // so instead we put it as extra on the scope |
| 100 | + scope.setExtra('server_action_form_data', formDataObject); |
| 101 | + } |
105 | 102 |
|
106 |
| - if (options.recordResponse !== undefined ? options.recordResponse : sendDefaultPii) { |
107 |
| - span?.setAttribute('server_action_result', result); |
108 |
| - } |
109 |
| - |
110 |
| - if (options.formData) { |
111 |
| - const formDataObject: Record<string, unknown> = {}; |
112 |
| - options.formData.forEach((value, key) => { |
113 |
| - if (typeof value === 'string') { |
114 |
| - formDataObject[key] = value; |
115 |
| - } else { |
116 |
| - formDataObject[key] = '[non-string value]'; |
117 |
| - } |
| 103 | + return startSpan( |
| 104 | + { |
| 105 | + op: 'function.server_action', |
| 106 | + name: `serverAction/${serverActionName}`, |
| 107 | + status: 'ok', |
| 108 | + ...traceparentData, |
| 109 | + metadata: { |
| 110 | + source: 'route', |
| 111 | + dynamicSamplingContext: traceparentData && !dynamicSamplingContext ? {} : dynamicSamplingContext, |
| 112 | + request: { |
| 113 | + headers: fullHeadersObject, |
| 114 | + }, |
| 115 | + }, |
| 116 | + }, |
| 117 | + async span => { |
| 118 | + const result = await handleCallbackErrors(callback, error => { |
| 119 | + captureException(error, { mechanism: { handled: false } }); |
118 | 120 | });
|
119 |
| - // Since formDataObject is not a primitive, we cannot store it on the span as attributes |
120 |
| - // so instead we put it as extra on the scope |
121 |
| - const scope = getCurrentScope(); |
122 |
| - scope.setExtra('server_action_form_data', formDataObject); |
123 |
| - } |
124 | 121 |
|
125 |
| - return result; |
126 |
| - }, |
127 |
| - ); |
| 122 | + if (options.recordResponse !== undefined ? options.recordResponse : sendDefaultPii) { |
| 123 | + span?.setAttribute('server_action_result', result); |
| 124 | + } |
| 125 | + |
| 126 | + return result; |
| 127 | + }, |
| 128 | + ); |
| 129 | + }); |
128 | 130 | } finally {
|
129 | 131 | if (!platformSupportsStreaming()) {
|
130 | 132 | // Lambdas require manual flushing to prevent execution freeze before the event is sent
|
|
0 commit comments