autotel 2.25.3 → 2.25.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/{chunk-FXKB7EPR.cjs → chunk-A5ZUL2RZ.cjs} +5 -5
  2. package/dist/{chunk-FXKB7EPR.cjs.map → chunk-A5ZUL2RZ.cjs.map} +1 -1
  3. package/dist/{chunk-SR35DG5A.js → chunk-BBBWDIYQ.js} +27 -13
  4. package/dist/chunk-BBBWDIYQ.js.map +1 -0
  5. package/dist/{chunk-3ZLYWPMY.js → chunk-CMUM4JQI.js} +3 -3
  6. package/dist/{chunk-3ZLYWPMY.js.map → chunk-CMUM4JQI.js.map} +1 -1
  7. package/dist/{chunk-AQXPGGQK.cjs → chunk-EEJGUBWV.cjs} +5 -5
  8. package/dist/{chunk-AQXPGGQK.cjs.map → chunk-EEJGUBWV.cjs.map} +1 -1
  9. package/dist/{chunk-W4EUTSB2.cjs → chunk-HZ3FYBJG.cjs} +27 -12
  10. package/dist/chunk-HZ3FYBJG.cjs.map +1 -0
  11. package/dist/{chunk-WOWTZ4EB.cjs → chunk-I6JPSD4R.cjs} +5 -5
  12. package/dist/{chunk-WOWTZ4EB.cjs.map → chunk-I6JPSD4R.cjs.map} +1 -1
  13. package/dist/{chunk-XRKAL7WJ.cjs → chunk-JSNUWSBH.cjs} +6 -6
  14. package/dist/chunk-JSNUWSBH.cjs.map +1 -0
  15. package/dist/{chunk-OWXXS4JB.cjs → chunk-MN6PZ4AN.cjs} +7 -7
  16. package/dist/{chunk-OWXXS4JB.cjs.map → chunk-MN6PZ4AN.cjs.map} +1 -1
  17. package/dist/{chunk-JM63D22M.js → chunk-OPTGXEVN.js} +368 -349
  18. package/dist/chunk-OPTGXEVN.js.map +1 -0
  19. package/dist/{chunk-PKXD2RMI.js → chunk-QDREXAD7.js} +3 -3
  20. package/dist/{chunk-PKXD2RMI.js.map → chunk-QDREXAD7.js.map} +1 -1
  21. package/dist/{chunk-RMGSBMQF.cjs → chunk-QQLP4M6W.cjs} +372 -353
  22. package/dist/chunk-QQLP4M6W.cjs.map +1 -0
  23. package/dist/{chunk-USSL3D6L.js → chunk-S4OFEXLA.js} +6 -6
  24. package/dist/chunk-S4OFEXLA.js.map +1 -0
  25. package/dist/{chunk-VVYSQXQL.js → chunk-WYP6OOCT.js} +3 -3
  26. package/dist/{chunk-VVYSQXQL.js.map → chunk-WYP6OOCT.js.map} +1 -1
  27. package/dist/{chunk-IFKDBL65.js → chunk-XB2GITM5.js} +3 -3
  28. package/dist/{chunk-IFKDBL65.js.map → chunk-XB2GITM5.js.map} +1 -1
  29. package/dist/correlation-id.cjs +10 -9
  30. package/dist/correlation-id.d.cts +4 -1
  31. package/dist/correlation-id.d.ts +4 -1
  32. package/dist/correlation-id.js +2 -1
  33. package/dist/decorators.cjs +4 -4
  34. package/dist/decorators.js +3 -3
  35. package/dist/event.cjs +6 -5
  36. package/dist/event.js +3 -2
  37. package/dist/functional.cjs +10 -10
  38. package/dist/functional.js +3 -3
  39. package/dist/http.cjs +2 -2
  40. package/dist/http.js +1 -1
  41. package/dist/index.cjs +45 -45
  42. package/dist/index.js +10 -10
  43. package/dist/messaging.cjs +7 -7
  44. package/dist/messaging.js +4 -4
  45. package/dist/semantic-helpers.cjs +8 -8
  46. package/dist/semantic-helpers.js +4 -4
  47. package/dist/webhook.cjs +4 -4
  48. package/dist/webhook.js +3 -3
  49. package/dist/workflow-distributed.cjs +5 -5
  50. package/dist/workflow-distributed.js +3 -3
  51. package/dist/workflow.cjs +8 -8
  52. package/dist/workflow.js +4 -4
  53. package/package.json +1 -1
  54. package/src/correlation-id.ts +10 -5
  55. package/src/functional.ts +440 -420
  56. package/src/trace-context.test.ts +73 -0
  57. package/src/trace-context.ts +44 -12
  58. package/dist/chunk-JM63D22M.js.map +0 -1
  59. package/dist/chunk-RMGSBMQF.cjs.map +0 -1
  60. package/dist/chunk-SR35DG5A.js.map +0 -1
  61. package/dist/chunk-USSL3D6L.js.map +0 -1
  62. package/dist/chunk-W4EUTSB2.cjs.map +0 -1
  63. package/dist/chunk-XRKAL7WJ.cjs.map +0 -1
package/src/functional.ts CHANGED
@@ -53,6 +53,7 @@ import { getEventQueue } from './track';
53
53
  import type { TraceContext } from './trace-context';
54
54
  import {
55
55
  createTraceContext,
56
+ enterOrRun,
56
57
  getActiveContextWithBaggage,
57
58
  getContextStorage,
58
59
  } from './trace-context';
@@ -768,160 +769,166 @@ function wrapWithTracing<TArgs extends unknown[], TReturn>(
768
769
  spanOptions.kind = options.spanKind;
769
770
  }
770
771
 
771
- return tracer.startActiveSpan(spanName, spanOptions, async (span) => {
772
- // Run within operation context so events can auto-capture operation.name
773
- return runInOperationContext(spanName, async () => {
774
- let shouldKeepSpan = true;
772
+ const parentContext = getActiveContextWithBaggage();
773
+ return tracer.startActiveSpan(
774
+ spanName,
775
+ spanOptions,
776
+ parentContext,
777
+ async (span) => {
778
+ // Run within operation context so events can auto-capture operation.name
779
+ return runInOperationContext(spanName, async () => {
780
+ let shouldKeepSpan = true;
781
+
782
+ setSpanName(span, spanName);
783
+
784
+ // Initialize context storage with the active context BEFORE creating trace context
785
+ const initialContext = context.active();
786
+ const contextStorage = getContextStorage();
787
+ if (!contextStorage.getStore()) {
788
+ enterOrRun(contextStorage, initialContext);
789
+ }
775
790
 
776
- setSpanName(span, spanName);
791
+ const ctxValue = createTraceContext(span);
792
+ const fn = fnFactory(ctxValue);
793
+ const argsAttributes = options.attributesFromArgs
794
+ ? options.attributesFromArgs(args)
795
+ : {};
777
796
 
778
- // Initialize context storage with the active context BEFORE creating trace context
779
- const initialContext = context.active();
780
- const contextStorage = getContextStorage();
781
- if (!contextStorage.getStore()) {
782
- contextStorage.enterWith(initialContext);
783
- }
797
+ const handleTailSampling = (
798
+ success: boolean,
799
+ duration: number,
800
+ error?: unknown,
801
+ ) => {
802
+ if (
803
+ needsTailSampling &&
804
+ 'shouldKeepTrace' in sampler &&
805
+ typeof sampler.shouldKeepTrace === 'function'
806
+ ) {
807
+ shouldKeepSpan = sampler.shouldKeepTrace(samplingContext, {
808
+ success,
809
+ duration,
810
+ error,
811
+ });
812
+ span.setAttribute(AUTOTEL_SAMPLING_TAIL_KEEP, shouldKeepSpan);
813
+ span.setAttribute(AUTOTEL_SAMPLING_TAIL_EVALUATED, true);
814
+ }
815
+ };
784
816
 
785
- const ctxValue = createTraceContext(span);
786
- const fn = fnFactory(ctxValue);
787
- const argsAttributes = options.attributesFromArgs
788
- ? options.attributesFromArgs(args)
789
- : {};
817
+ const onSuccess = async (result: TReturn) => {
818
+ const duration = performance.now() - startTime;
790
819
 
791
- const handleTailSampling = (
792
- success: boolean,
793
- duration: number,
794
- error?: unknown,
795
- ) => {
796
- if (
797
- needsTailSampling &&
798
- 'shouldKeepTrace' in sampler &&
799
- typeof sampler.shouldKeepTrace === 'function'
800
- ) {
801
- shouldKeepSpan = sampler.shouldKeepTrace(samplingContext, {
802
- success,
803
- duration,
804
- error,
820
+ callCounter?.add(1, {
821
+ operation: spanName,
822
+ status: 'success',
805
823
  });
806
- span.setAttribute(AUTOTEL_SAMPLING_TAIL_KEEP, shouldKeepSpan);
807
- span.setAttribute(AUTOTEL_SAMPLING_TAIL_EVALUATED, true);
808
- }
809
- };
810
824
 
811
- const onSuccess = async (result: TReturn) => {
812
- const duration = performance.now() - startTime;
813
-
814
- callCounter?.add(1, {
815
- operation: spanName,
816
- status: 'success',
817
- });
825
+ durationHistogram?.record(duration, {
826
+ operation: spanName,
827
+ status: 'success',
828
+ });
818
829
 
819
- durationHistogram?.record(duration, {
820
- operation: spanName,
821
- status: 'success',
822
- });
830
+ const resultAttributes = options.attributesFromResult
831
+ ? options.attributesFromResult(result)
832
+ : {};
833
+
834
+ span.setStatus({ code: SpanStatusCode.OK });
835
+ span.setAttributes({
836
+ ...argsAttributes,
837
+ ...resultAttributes,
838
+ 'operation.name': spanName,
839
+ 'code.function': spanName,
840
+ 'operation.duration': duration,
841
+ 'operation.success': true,
842
+ });
823
843
 
824
- const resultAttributes = options.attributesFromResult
825
- ? options.attributesFromResult(result)
826
- : {};
844
+ handleTailSampling(true, duration);
827
845
 
828
- span.setStatus({ code: SpanStatusCode.OK });
829
- span.setAttributes({
830
- ...argsAttributes,
831
- ...resultAttributes,
832
- 'operation.name': spanName,
833
- 'code.function': spanName,
834
- 'operation.duration': duration,
835
- 'operation.success': true,
836
- });
837
-
838
- handleTailSampling(true, duration);
846
+ span.end();
847
+ await flushIfNeeded();
848
+ return result;
849
+ };
839
850
 
840
- span.end();
841
- await flushIfNeeded();
842
- return result;
843
- };
851
+ const onError = async (error: unknown): Promise<never> => {
852
+ const duration = performance.now() - startTime;
844
853
 
845
- const onError = async (error: unknown): Promise<never> => {
846
- const duration = performance.now() - startTime;
854
+ callCounter?.add(1, {
855
+ operation: spanName,
856
+ status: 'error',
857
+ });
847
858
 
848
- callCounter?.add(1, {
849
- operation: spanName,
850
- status: 'error',
851
- });
859
+ durationHistogram?.record(duration, {
860
+ operation: spanName,
861
+ status: 'error',
862
+ });
852
863
 
853
- durationHistogram?.record(duration, {
854
- operation: spanName,
855
- status: 'error',
856
- });
864
+ const errorMessage =
865
+ error instanceof Error ? error.message : 'Unknown error';
866
+ const truncatedMessage = truncateErrorMessage(errorMessage);
857
867
 
858
- const errorMessage =
859
- error instanceof Error ? error.message : 'Unknown error';
860
- const truncatedMessage = truncateErrorMessage(errorMessage);
868
+ span.setStatus({
869
+ code: SpanStatusCode.ERROR,
870
+ message: truncatedMessage,
871
+ });
861
872
 
862
- span.setStatus({
863
- code: SpanStatusCode.ERROR,
864
- message: truncatedMessage,
865
- });
873
+ span.setAttributes({
874
+ ...argsAttributes,
875
+ 'operation.name': spanName,
876
+ 'code.function': spanName,
877
+ 'operation.duration': duration,
878
+ 'operation.success': false,
879
+ error: true,
880
+ 'exception.type':
881
+ error instanceof Error ? error.constructor.name : 'Error',
882
+ 'exception.message': truncatedMessage,
883
+ });
866
884
 
867
- span.setAttributes({
868
- ...argsAttributes,
869
- 'operation.name': spanName,
870
- 'code.function': spanName,
871
- 'operation.duration': duration,
872
- 'operation.success': false,
873
- error: true,
874
- 'exception.type':
875
- error instanceof Error ? error.constructor.name : 'Error',
876
- 'exception.message': truncatedMessage,
877
- });
885
+ if (error instanceof Error && error.stack) {
886
+ span.setAttribute(
887
+ 'exception.stack',
888
+ error.stack.slice(0, MAX_ERROR_MESSAGE_LENGTH),
889
+ );
890
+ }
878
891
 
879
- if (error instanceof Error && error.stack) {
880
- span.setAttribute(
881
- 'exception.stack',
882
- error.stack.slice(0, MAX_ERROR_MESSAGE_LENGTH),
892
+ span.recordException(
893
+ error instanceof Error ? error : new Error(String(error)),
883
894
  );
884
- }
885
895
 
886
- span.recordException(
887
- error instanceof Error ? error : new Error(String(error)),
888
- );
889
-
890
- handleTailSampling(false, duration, error);
896
+ handleTailSampling(false, duration, error);
891
897
 
892
- span.end();
893
- await flushIfNeeded();
894
- throw error;
895
- };
896
-
897
- try {
898
- callCounter?.add(1, {
899
- operation: spanName,
900
- status: 'started',
901
- });
898
+ span.end();
899
+ await flushIfNeeded();
900
+ throw error;
901
+ };
902
902
 
903
- // Execute the user's function with the updated context
904
- // This ensures ctx.setBaggage() changes are visible to OpenTelemetry operations
905
- // (like BaggageSpanProcessor, child spans, etc.)
906
- // We use getActiveContextWithBaggage() which checks the stored context,
907
- // so if baggage is set during execution, it will be picked up
908
- const executeWithContext = async () => {
909
- // Get the current context (may have been updated by ctx.setBaggage())
910
- const currentContext = getActiveContextWithBaggage();
911
- // Establish the context in OpenTelemetry's context manager
912
- return context.with(currentContext, async () => {
913
- return fn.call(this, ...args);
903
+ try {
904
+ callCounter?.add(1, {
905
+ operation: spanName,
906
+ status: 'started',
914
907
  });
915
- };
916
- const result = await executeWithContext();
917
908
 
918
- return await onSuccess(result);
919
- } catch (error) {
920
- await onError(error);
921
- throw error;
922
- }
923
- });
924
- });
909
+ // Execute the user's function with the updated context
910
+ // This ensures ctx.setBaggage() changes are visible to OpenTelemetry operations
911
+ // (like BaggageSpanProcessor, child spans, etc.)
912
+ // We use getActiveContextWithBaggage() which checks the stored context,
913
+ // so if baggage is set during execution, it will be picked up
914
+ const executeWithContext = async () => {
915
+ // Get the current context (may have been updated by ctx.setBaggage())
916
+ const currentContext = getActiveContextWithBaggage();
917
+ // Establish the context in OpenTelemetry's context manager
918
+ return context.with(currentContext, async () => {
919
+ return fn.call(this, ...args);
920
+ });
921
+ };
922
+ const result = await executeWithContext();
923
+
924
+ return await onSuccess(result);
925
+ } catch (error) {
926
+ await onError(error);
927
+ throw error;
928
+ }
929
+ });
930
+ },
931
+ );
925
932
  };
926
933
 
927
934
  // Mark as instrumented to prevent double-wrapping
@@ -1075,143 +1082,149 @@ function wrapWithTracingSync<TArgs extends unknown[], TReturn>(
1075
1082
  spanOptions.kind = options.spanKind;
1076
1083
  }
1077
1084
 
1078
- return tracer.startActiveSpan(spanName, spanOptions, (span) => {
1079
- // Run within operation context so events can auto-capture operation.name
1080
- return runInOperationContext(spanName, () => {
1081
- let shouldKeepSpan = true;
1082
-
1083
- // Store span name for trace context helpers
1084
- setSpanName(span, spanName);
1085
-
1086
- // Create trace context for this span using shared utility
1087
- const ctxValue = createTraceContext(span);
1085
+ const parentContext = getActiveContextWithBaggage();
1086
+ return tracer.startActiveSpan(
1087
+ spanName,
1088
+ spanOptions,
1089
+ parentContext,
1090
+ (span) => {
1091
+ // Run within operation context so events can auto-capture operation.name
1092
+ return runInOperationContext(spanName, () => {
1093
+ let shouldKeepSpan = true;
1094
+
1095
+ // Store span name for trace context helpers
1096
+ setSpanName(span, spanName);
1097
+
1098
+ // Create trace context for this span using shared utility
1099
+ const ctxValue = createTraceContext(span);
1100
+
1101
+ // Get the actual function from the factory
1102
+ const fn = fnFactory(ctxValue);
1103
+
1104
+ // Extract attributes only when actually tracing
1105
+ // This avoids expensive preprocessing when sampling rejects the trace
1106
+ const argsAttributes = options.attributesFromArgs
1107
+ ? options.attributesFromArgs(args)
1108
+ : {};
1088
1109
 
1089
- // Get the actual function from the factory
1090
- const fn = fnFactory(ctxValue);
1110
+ const handleTailSampling = (
1111
+ success: boolean,
1112
+ duration: number,
1113
+ error?: unknown,
1114
+ ) => {
1115
+ if (
1116
+ needsTailSampling &&
1117
+ 'shouldKeepTrace' in sampler &&
1118
+ typeof sampler.shouldKeepTrace === 'function'
1119
+ ) {
1120
+ shouldKeepSpan = sampler.shouldKeepTrace(samplingContext, {
1121
+ success,
1122
+ duration,
1123
+ error,
1124
+ });
1125
+ span.setAttribute(AUTOTEL_SAMPLING_TAIL_KEEP, shouldKeepSpan);
1126
+ span.setAttribute(AUTOTEL_SAMPLING_TAIL_EVALUATED, true);
1127
+ }
1128
+ };
1091
1129
 
1092
- // Extract attributes only when actually tracing
1093
- // This avoids expensive preprocessing when sampling rejects the trace
1094
- const argsAttributes = options.attributesFromArgs
1095
- ? options.attributesFromArgs(args)
1096
- : {};
1130
+ const onSuccess = (result: TReturn) => {
1131
+ const duration = performance.now() - startTime;
1097
1132
 
1098
- const handleTailSampling = (
1099
- success: boolean,
1100
- duration: number,
1101
- error?: unknown,
1102
- ) => {
1103
- if (
1104
- needsTailSampling &&
1105
- 'shouldKeepTrace' in sampler &&
1106
- typeof sampler.shouldKeepTrace === 'function'
1107
- ) {
1108
- shouldKeepSpan = sampler.shouldKeepTrace(samplingContext, {
1109
- success,
1110
- duration,
1111
- error,
1133
+ callCounter?.add(1, {
1134
+ operation: spanName,
1135
+ status: 'success',
1112
1136
  });
1113
- span.setAttribute(AUTOTEL_SAMPLING_TAIL_KEEP, shouldKeepSpan);
1114
- span.setAttribute(AUTOTEL_SAMPLING_TAIL_EVALUATED, true);
1115
- }
1116
- };
1117
1137
 
1118
- const onSuccess = (result: TReturn) => {
1119
- const duration = performance.now() - startTime;
1120
-
1121
- callCounter?.add(1, {
1122
- operation: spanName,
1123
- status: 'success',
1124
- });
1138
+ durationHistogram?.record(duration, {
1139
+ operation: spanName,
1140
+ status: 'success',
1141
+ });
1125
1142
 
1126
- durationHistogram?.record(duration, {
1127
- operation: spanName,
1128
- status: 'success',
1129
- });
1143
+ const resultAttributes = options.attributesFromResult
1144
+ ? options.attributesFromResult(result)
1145
+ : {};
1146
+
1147
+ span.setStatus({ code: SpanStatusCode.OK });
1148
+ span.setAttributes({
1149
+ ...argsAttributes,
1150
+ ...resultAttributes,
1151
+ 'operation.name': spanName,
1152
+ 'code.function': spanName,
1153
+ 'operation.duration': duration,
1154
+ 'operation.success': true,
1155
+ });
1130
1156
 
1131
- const resultAttributes = options.attributesFromResult
1132
- ? options.attributesFromResult(result)
1133
- : {};
1157
+ handleTailSampling(true, duration);
1134
1158
 
1135
- span.setStatus({ code: SpanStatusCode.OK });
1136
- span.setAttributes({
1137
- ...argsAttributes,
1138
- ...resultAttributes,
1139
- 'operation.name': spanName,
1140
- 'code.function': spanName,
1141
- 'operation.duration': duration,
1142
- 'operation.success': true,
1143
- });
1144
-
1145
- handleTailSampling(true, duration);
1159
+ span.end();
1160
+ void flushIfNeeded();
1161
+ return result;
1162
+ };
1146
1163
 
1147
- span.end();
1148
- void flushIfNeeded();
1149
- return result;
1150
- };
1164
+ const onError = (error: unknown): never => {
1165
+ const duration = performance.now() - startTime;
1151
1166
 
1152
- const onError = (error: unknown): never => {
1153
- const duration = performance.now() - startTime;
1167
+ callCounter?.add(1, {
1168
+ operation: spanName,
1169
+ status: 'error',
1170
+ });
1154
1171
 
1155
- callCounter?.add(1, {
1156
- operation: spanName,
1157
- status: 'error',
1158
- });
1172
+ durationHistogram?.record(duration, {
1173
+ operation: spanName,
1174
+ status: 'error',
1175
+ });
1159
1176
 
1160
- durationHistogram?.record(duration, {
1161
- operation: spanName,
1162
- status: 'error',
1163
- });
1177
+ const errorMessage =
1178
+ error instanceof Error ? error.message : 'Unknown error';
1179
+ const truncatedMessage = truncateErrorMessage(errorMessage);
1164
1180
 
1165
- const errorMessage =
1166
- error instanceof Error ? error.message : 'Unknown error';
1167
- const truncatedMessage = truncateErrorMessage(errorMessage);
1181
+ span.setStatus({
1182
+ code: SpanStatusCode.ERROR,
1183
+ message: truncatedMessage,
1184
+ });
1168
1185
 
1169
- span.setStatus({
1170
- code: SpanStatusCode.ERROR,
1171
- message: truncatedMessage,
1172
- });
1186
+ span.setAttributes({
1187
+ ...argsAttributes,
1188
+ 'operation.name': spanName,
1189
+ 'code.function': spanName,
1190
+ 'operation.duration': duration,
1191
+ 'operation.success': false,
1192
+ error: true,
1193
+ 'exception.type':
1194
+ error instanceof Error ? error.constructor.name : 'Error',
1195
+ 'exception.message': truncatedMessage,
1196
+ });
1173
1197
 
1174
- span.setAttributes({
1175
- ...argsAttributes,
1176
- 'operation.name': spanName,
1177
- 'code.function': spanName,
1178
- 'operation.duration': duration,
1179
- 'operation.success': false,
1180
- error: true,
1181
- 'exception.type':
1182
- error instanceof Error ? error.constructor.name : 'Error',
1183
- 'exception.message': truncatedMessage,
1184
- });
1198
+ span.recordException(
1199
+ error instanceof Error ? error : new Error(String(error)),
1200
+ );
1185
1201
 
1186
- span.recordException(
1187
- error instanceof Error ? error : new Error(String(error)),
1188
- );
1202
+ handleTailSampling(false, duration, error);
1189
1203
 
1190
- handleTailSampling(false, duration, error);
1204
+ span.end();
1205
+ void flushIfNeeded();
1206
+ throw error;
1207
+ };
1191
1208
 
1192
- span.end();
1193
- void flushIfNeeded();
1194
- throw error;
1195
- };
1209
+ try {
1210
+ callCounter?.add(1, {
1211
+ operation: spanName,
1212
+ status: 'started',
1213
+ });
1196
1214
 
1197
- try {
1198
- callCounter?.add(1, {
1199
- operation: spanName,
1200
- status: 'started',
1201
- });
1215
+ const result = fn.call(this, ...args);
1202
1216
 
1203
- const result = fn.call(this, ...args);
1217
+ if (result instanceof Promise) {
1218
+ return result.then(onSuccess, onError);
1219
+ }
1204
1220
 
1205
- if (result instanceof Promise) {
1206
- return result.then(onSuccess, onError);
1221
+ return onSuccess(result);
1222
+ } catch (error) {
1223
+ return onError(error);
1207
1224
  }
1208
-
1209
- return onSuccess(result);
1210
- } catch (error) {
1211
- return onError(error);
1212
- }
1213
- });
1214
- });
1225
+ });
1226
+ },
1227
+ );
1215
1228
  }
1216
1229
 
1217
1230
  // Mark as instrumented to prevent double-wrapping
@@ -1336,215 +1349,221 @@ function executeImmediately<TReturn = unknown>(
1336
1349
  spanOptions.kind = options.spanKind;
1337
1350
  }
1338
1351
 
1339
- return tracer.startActiveSpan(spanName, spanOptions, (span) => {
1340
- return runInOperationContext(spanName, () => {
1341
- let shouldKeepSpan = true;
1342
-
1343
- setSpanName(span, spanName);
1344
- const ctxValue = createTraceContext(span);
1345
-
1346
- const handleTailSampling = (
1347
- success: boolean,
1348
- duration: number,
1349
- error?: unknown,
1350
- ) => {
1351
- if (
1352
- needsTailSampling &&
1353
- 'shouldKeepTrace' in sampler &&
1354
- typeof sampler.shouldKeepTrace === 'function'
1355
- ) {
1356
- shouldKeepSpan = sampler.shouldKeepTrace(samplingContext, {
1357
- success,
1358
- duration,
1359
- error,
1360
- });
1361
- span.setAttribute(AUTOTEL_SAMPLING_TAIL_KEEP, shouldKeepSpan);
1362
- span.setAttribute(AUTOTEL_SAMPLING_TAIL_EVALUATED, true);
1363
- }
1364
- };
1352
+ const parentContext = getActiveContextWithBaggage();
1353
+ return tracer.startActiveSpan(
1354
+ spanName,
1355
+ spanOptions,
1356
+ parentContext,
1357
+ (span) => {
1358
+ return runInOperationContext(spanName, () => {
1359
+ let shouldKeepSpan = true;
1365
1360
 
1366
- // Sync handlers for synchronous results (can't await)
1367
- // NOTE: forceFlushOnShutdown will NOT block for synchronous trace() calls
1368
- // Flush is fire-and-forget, so spans may be dropped if process exits immediately
1369
- const onSuccessSync = (result: TReturn) => {
1370
- const duration = performance.now() - startTime;
1361
+ setSpanName(span, spanName);
1362
+ const ctxValue = createTraceContext(span);
1371
1363
 
1372
- callCounter?.add(1, {
1373
- operation: spanName,
1374
- status: 'success',
1375
- });
1364
+ const handleTailSampling = (
1365
+ success: boolean,
1366
+ duration: number,
1367
+ error?: unknown,
1368
+ ) => {
1369
+ if (
1370
+ needsTailSampling &&
1371
+ 'shouldKeepTrace' in sampler &&
1372
+ typeof sampler.shouldKeepTrace === 'function'
1373
+ ) {
1374
+ shouldKeepSpan = sampler.shouldKeepTrace(samplingContext, {
1375
+ success,
1376
+ duration,
1377
+ error,
1378
+ });
1379
+ span.setAttribute(AUTOTEL_SAMPLING_TAIL_KEEP, shouldKeepSpan);
1380
+ span.setAttribute(AUTOTEL_SAMPLING_TAIL_EVALUATED, true);
1381
+ }
1382
+ };
1376
1383
 
1377
- durationHistogram?.record(duration, {
1378
- operation: spanName,
1379
- status: 'success',
1380
- });
1384
+ // Sync handlers for synchronous results (can't await)
1385
+ // NOTE: forceFlushOnShutdown will NOT block for synchronous trace() calls
1386
+ // Flush is fire-and-forget, so spans may be dropped if process exits immediately
1387
+ const onSuccessSync = (result: TReturn) => {
1388
+ const duration = performance.now() - startTime;
1381
1389
 
1382
- span.setStatus({ code: SpanStatusCode.OK });
1383
- span.setAttributes({
1384
- 'operation.name': spanName,
1385
- 'code.function': spanName,
1386
- 'operation.duration': duration,
1387
- 'operation.success': true,
1388
- });
1390
+ callCounter?.add(1, {
1391
+ operation: spanName,
1392
+ status: 'success',
1393
+ });
1389
1394
 
1390
- handleTailSampling(true, duration);
1395
+ durationHistogram?.record(duration, {
1396
+ operation: spanName,
1397
+ status: 'success',
1398
+ });
1391
1399
 
1392
- span.end();
1393
- void flushIfNeeded();
1394
- return result;
1395
- };
1400
+ span.setStatus({ code: SpanStatusCode.OK });
1401
+ span.setAttributes({
1402
+ 'operation.name': spanName,
1403
+ 'code.function': spanName,
1404
+ 'operation.duration': duration,
1405
+ 'operation.success': true,
1406
+ });
1396
1407
 
1397
- const onErrorSync = (error: unknown): never => {
1398
- const duration = performance.now() - startTime;
1408
+ handleTailSampling(true, duration);
1399
1409
 
1400
- callCounter?.add(1, {
1401
- operation: spanName,
1402
- status: 'error',
1403
- });
1410
+ span.end();
1411
+ void flushIfNeeded();
1412
+ return result;
1413
+ };
1404
1414
 
1405
- durationHistogram?.record(duration, {
1406
- operation: spanName,
1407
- status: 'error',
1408
- });
1415
+ const onErrorSync = (error: unknown): never => {
1416
+ const duration = performance.now() - startTime;
1409
1417
 
1410
- const errorMessage =
1411
- error instanceof Error ? error.message : 'Unknown error';
1412
- const truncatedMessage = truncateErrorMessage(errorMessage);
1418
+ callCounter?.add(1, {
1419
+ operation: spanName,
1420
+ status: 'error',
1421
+ });
1413
1422
 
1414
- span.setStatus({
1415
- code: SpanStatusCode.ERROR,
1416
- message: truncatedMessage,
1417
- });
1423
+ durationHistogram?.record(duration, {
1424
+ operation: spanName,
1425
+ status: 'error',
1426
+ });
1418
1427
 
1419
- span.setAttributes({
1420
- 'operation.name': spanName,
1421
- 'code.function': spanName,
1422
- 'operation.duration': duration,
1423
- 'operation.success': false,
1424
- error: true,
1425
- 'exception.type':
1426
- error instanceof Error ? error.constructor.name : 'Error',
1427
- 'exception.message': truncatedMessage,
1428
- });
1428
+ const errorMessage =
1429
+ error instanceof Error ? error.message : 'Unknown error';
1430
+ const truncatedMessage = truncateErrorMessage(errorMessage);
1431
+
1432
+ span.setStatus({
1433
+ code: SpanStatusCode.ERROR,
1434
+ message: truncatedMessage,
1435
+ });
1436
+
1437
+ span.setAttributes({
1438
+ 'operation.name': spanName,
1439
+ 'code.function': spanName,
1440
+ 'operation.duration': duration,
1441
+ 'operation.success': false,
1442
+ error: true,
1443
+ 'exception.type':
1444
+ error instanceof Error ? error.constructor.name : 'Error',
1445
+ 'exception.message': truncatedMessage,
1446
+ });
1447
+
1448
+ if (error instanceof Error && error.stack) {
1449
+ span.setAttribute(
1450
+ 'exception.stack',
1451
+ error.stack.slice(0, MAX_ERROR_MESSAGE_LENGTH),
1452
+ );
1453
+ }
1429
1454
 
1430
- if (error instanceof Error && error.stack) {
1431
- span.setAttribute(
1432
- 'exception.stack',
1433
- error.stack.slice(0, MAX_ERROR_MESSAGE_LENGTH),
1455
+ span.recordException(
1456
+ error instanceof Error ? error : new Error(String(error)),
1434
1457
  );
1435
- }
1436
1458
 
1437
- span.recordException(
1438
- error instanceof Error ? error : new Error(String(error)),
1439
- );
1459
+ handleTailSampling(false, duration, error);
1440
1460
 
1441
- handleTailSampling(false, duration, error);
1461
+ span.end();
1462
+ void flushIfNeeded();
1463
+ throw error;
1464
+ };
1442
1465
 
1443
- span.end();
1444
- void flushIfNeeded();
1445
- throw error;
1446
- };
1466
+ // Async handlers for Promise results (await flush)
1467
+ const onSuccessAsync = async (result: TReturn) => {
1468
+ const duration = performance.now() - startTime;
1447
1469
 
1448
- // Async handlers for Promise results (await flush)
1449
- const onSuccessAsync = async (result: TReturn) => {
1450
- const duration = performance.now() - startTime;
1470
+ callCounter?.add(1, {
1471
+ operation: spanName,
1472
+ status: 'success',
1473
+ });
1451
1474
 
1452
- callCounter?.add(1, {
1453
- operation: spanName,
1454
- status: 'success',
1455
- });
1475
+ durationHistogram?.record(duration, {
1476
+ operation: spanName,
1477
+ status: 'success',
1478
+ });
1456
1479
 
1457
- durationHistogram?.record(duration, {
1458
- operation: spanName,
1459
- status: 'success',
1460
- });
1480
+ span.setStatus({ code: SpanStatusCode.OK });
1481
+ span.setAttributes({
1482
+ 'operation.name': spanName,
1483
+ 'code.function': spanName,
1484
+ 'operation.duration': duration,
1485
+ 'operation.success': true,
1486
+ });
1461
1487
 
1462
- span.setStatus({ code: SpanStatusCode.OK });
1463
- span.setAttributes({
1464
- 'operation.name': spanName,
1465
- 'code.function': spanName,
1466
- 'operation.duration': duration,
1467
- 'operation.success': true,
1468
- });
1488
+ handleTailSampling(true, duration);
1469
1489
 
1470
- handleTailSampling(true, duration);
1490
+ span.end();
1491
+ await flushIfNeeded();
1492
+ return result;
1493
+ };
1471
1494
 
1472
- span.end();
1473
- await flushIfNeeded();
1474
- return result;
1475
- };
1495
+ const onErrorAsync = async (error: unknown): Promise<never> => {
1496
+ const duration = performance.now() - startTime;
1476
1497
 
1477
- const onErrorAsync = async (error: unknown): Promise<never> => {
1478
- const duration = performance.now() - startTime;
1498
+ callCounter?.add(1, {
1499
+ operation: spanName,
1500
+ status: 'error',
1501
+ });
1479
1502
 
1480
- callCounter?.add(1, {
1481
- operation: spanName,
1482
- status: 'error',
1483
- });
1503
+ durationHistogram?.record(duration, {
1504
+ operation: spanName,
1505
+ status: 'error',
1506
+ });
1484
1507
 
1485
- durationHistogram?.record(duration, {
1486
- operation: spanName,
1487
- status: 'error',
1488
- });
1508
+ const errorMessage =
1509
+ error instanceof Error ? error.message : 'Unknown error';
1510
+ const truncatedMessage = truncateErrorMessage(errorMessage);
1489
1511
 
1490
- const errorMessage =
1491
- error instanceof Error ? error.message : 'Unknown error';
1492
- const truncatedMessage = truncateErrorMessage(errorMessage);
1512
+ span.setStatus({
1513
+ code: SpanStatusCode.ERROR,
1514
+ message: truncatedMessage,
1515
+ });
1493
1516
 
1494
- span.setStatus({
1495
- code: SpanStatusCode.ERROR,
1496
- message: truncatedMessage,
1497
- });
1517
+ span.setAttributes({
1518
+ 'operation.name': spanName,
1519
+ 'code.function': spanName,
1520
+ 'operation.duration': duration,
1521
+ 'operation.success': false,
1522
+ error: true,
1523
+ 'exception.type':
1524
+ error instanceof Error ? error.constructor.name : 'Error',
1525
+ 'exception.message': truncatedMessage,
1526
+ });
1498
1527
 
1499
- span.setAttributes({
1500
- 'operation.name': spanName,
1501
- 'code.function': spanName,
1502
- 'operation.duration': duration,
1503
- 'operation.success': false,
1504
- error: true,
1505
- 'exception.type':
1506
- error instanceof Error ? error.constructor.name : 'Error',
1507
- 'exception.message': truncatedMessage,
1508
- });
1528
+ if (error instanceof Error && error.stack) {
1529
+ span.setAttribute(
1530
+ 'exception.stack',
1531
+ error.stack.slice(0, MAX_ERROR_MESSAGE_LENGTH),
1532
+ );
1533
+ }
1509
1534
 
1510
- if (error instanceof Error && error.stack) {
1511
- span.setAttribute(
1512
- 'exception.stack',
1513
- error.stack.slice(0, MAX_ERROR_MESSAGE_LENGTH),
1535
+ span.recordException(
1536
+ error instanceof Error ? error : new Error(String(error)),
1514
1537
  );
1515
- }
1516
1538
 
1517
- span.recordException(
1518
- error instanceof Error ? error : new Error(String(error)),
1519
- );
1539
+ handleTailSampling(false, duration, error);
1520
1540
 
1521
- handleTailSampling(false, duration, error);
1541
+ span.end();
1542
+ await flushIfNeeded();
1543
+ throw error;
1544
+ };
1522
1545
 
1523
- span.end();
1524
- await flushIfNeeded();
1525
- throw error;
1526
- };
1546
+ try {
1547
+ callCounter?.add(1, {
1548
+ operation: spanName,
1549
+ status: 'started',
1550
+ });
1527
1551
 
1528
- try {
1529
- callCounter?.add(1, {
1530
- operation: spanName,
1531
- status: 'started',
1532
- });
1552
+ const result = fn(ctxValue);
1533
1553
 
1534
- const result = fn(ctxValue);
1554
+ // Check if result is a Promise - use async handlers to await flush
1555
+ if (result instanceof Promise) {
1556
+ return result.then(onSuccessAsync, onErrorAsync);
1557
+ }
1535
1558
 
1536
- // Check if result is a Promise - use async handlers to await flush
1537
- if (result instanceof Promise) {
1538
- return result.then(onSuccessAsync, onErrorAsync);
1559
+ // Synchronous result - use sync handlers
1560
+ return onSuccessSync(result);
1561
+ } catch (error) {
1562
+ return onErrorSync(error);
1539
1563
  }
1540
-
1541
- // Synchronous result - use sync handlers
1542
- return onSuccessSync(result);
1543
- } catch (error) {
1544
- return onErrorSync(error);
1545
- }
1546
- });
1547
- });
1564
+ });
1565
+ },
1566
+ );
1548
1567
  }
1549
1568
 
1550
1569
  /**
@@ -2212,7 +2231,8 @@ export function span<T = unknown>(
2212
2231
  });
2213
2232
  };
2214
2233
 
2215
- const result = tracer.startActiveSpan(name, executeSpan);
2234
+ const parentContext = getActiveContextWithBaggage();
2235
+ const result = tracer.startActiveSpan(name, {}, parentContext, executeSpan);
2216
2236
 
2217
2237
  // tracer.startActiveSpan might return a Promise even for sync callbacks
2218
2238
  // Check if it's a Promise and handle accordingly
@@ -2357,8 +2377,8 @@ export function withBaggage<T = unknown>(
2357
2377
  const ctxStorage = getContextStorage();
2358
2378
  const previousStored = ctxStorage.getStore();
2359
2379
  const baggageEnrichedStored = previousStored
2360
- ? propagation.setBaggage(previousStored, updatedBaggage)
2361
- : newContext;
2380
+ ? { value: propagation.setBaggage(previousStored.value, updatedBaggage) }
2381
+ : { value: newContext };
2362
2382
 
2363
2383
  // Run the function within the new context, scoped properly
2364
2384
  const result = previousStored