Skip to content

Commit 8c3facd

Browse files
committed
feat(cloudflare): Consolidate startNewTrace and linkPreviousTrace
1 parent f7f558e commit 8c3facd

File tree

3 files changed

+18
-27
lines changed

3 files changed

+18
-27
lines changed

packages/cloudflare/src/durableobject.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ export function instrumentDurableObjectWithSentry<
8484
if (obj.alarm && typeof obj.alarm === 'function') {
8585
// Alarms are independent invocations, so we start a new trace and link to the previous alarm
8686
obj.alarm = wrapMethodWithSentry(
87-
{ options, context, spanName: 'alarm', spanOp: 'function', startNewTrace: true, linkPreviousTrace: true },
87+
{ options, context, spanName: 'alarm', spanOp: 'function', startNewTrace: true },
8888
obj.alarm,
8989
);
9090
}

packages/cloudflare/src/wrapMethodWithSentry.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,14 @@ type MethodWrapperOptions = {
3030
/**
3131
* If true, starts a fresh trace instead of inheriting from a parent trace.
3232
* Useful for scheduled/independent invocations like alarms.
33-
* @default false
34-
*/
35-
startNewTrace?: boolean;
36-
/**
37-
* If true, stores the current span context and links to the previous invocation's span.
38-
* Requires `startNewTrace` to be true. Uses Durable Object storage to persist the link.
39-
* The link is set asynchronously via `span.addLinks()` in a `waitUntil` to avoid blocking.
33+
*
34+
* If true, it also stores the current span context and links to the previous invocation's span.
35+
* Uses Durable Object storage to persist the link. The link is set asynchronously via `span.addLinks()`
36+
* in a `waitUntil` to avoid blocking.
4037
*
4138
* @default false
4239
*/
43-
linkPreviousTrace?: boolean;
40+
startNewTrace?: boolean;
4441
};
4542

4643
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -68,7 +65,7 @@ export function wrapMethodWithSentry<T extends OriginalMethod>(
6865
original =>
6966
new Proxy(original, {
7067
apply(target, thisArg, args: Parameters<T>) {
71-
const { startNewTrace, linkPreviousTrace } = wrapperOptions;
68+
const { startNewTrace } = wrapperOptions;
7269

7370
// For startNewTrace, always use withIsolationScope to ensure a fresh scope
7471
// Otherwise, use existing client's scope or isolation scope
@@ -102,7 +99,7 @@ export function wrapMethodWithSentry<T extends OriginalMethod>(
10299
const methodName = wrapperOptions.spanName || 'unknown';
103100

104101
const teardown = async (): Promise<void> => {
105-
if (linkPreviousTrace && storage) {
102+
if (startNewTrace && storage) {
106103
await storeSpanContext(storage, methodName);
107104
}
108105
await flushAndDispose(clientToDispose);
@@ -149,7 +146,6 @@ export function wrapMethodWithSentry<T extends OriginalMethod>(
149146
}
150147
}
151148

152-
const spanName = wrapperOptions.spanName || methodName;
153149
const attributes = wrapperOptions.spanOp
154150
? {
155151
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: wrapperOptions.spanOp,
@@ -158,10 +154,10 @@ export function wrapMethodWithSentry<T extends OriginalMethod>(
158154
: {};
159155

160156
const executeSpan = (): unknown => {
161-
return startSpan({ name: spanName, attributes }, span => {
157+
return startSpan({ name: methodName, attributes }, span => {
162158
// When linking to previous trace, fetch the stored context and add links asynchronously
163159
// This avoids blocking the response while fetching from storage
164-
if (linkPreviousTrace && storage) {
160+
if (startNewTrace && storage) {
165161
waitUntil?.(
166162
getStoredSpanContext(storage, methodName).then(storedContext => {
167163
if (storedContext) {

packages/cloudflare/test/wrapMethodWithSentry.test.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ describe('wrapMethodWithSentry', () => {
147147
expect(handler).toHaveBeenCalled();
148148
});
149149

150-
it('does not change sync/async behavior when linkPreviousTrace is true (links are set via waitUntil)', () => {
150+
it('does not change sync/async behavior when startNewTrace is true (links are set via waitUntil)', () => {
151151
const handler = vi.fn().mockReturnValue('sync-result');
152152
const mockStorage = {
153153
get: vi.fn().mockResolvedValue(undefined),
@@ -164,13 +164,12 @@ describe('wrapMethodWithSentry', () => {
164164
context,
165165
spanName: 'alarm',
166166
startNewTrace: true,
167-
linkPreviousTrace: true,
168167
};
169168

170169
const wrapped = wrapMethodWithSentry(options, handler);
171170
const result = wrapped();
172171

173-
// linkPreviousTrace does not make the result async - links are set via waitUntil
172+
// startNewTrace does not make the result async - links are set via waitUntil
174173
expect(result).not.toBeInstanceOf(Promise);
175174
expect(result).toBe('sync-result');
176175

@@ -345,8 +344,8 @@ describe('wrapMethodWithSentry', () => {
345344
});
346345
});
347346

348-
describe('linkPreviousTrace option', () => {
349-
it('retrieves stored span context when linkPreviousTrace is true', async () => {
347+
describe('span linking', () => {
348+
it('retrieves stored span context when startNewTrace is true', async () => {
350349
const storedContext = {
351350
traceId: 'previous-trace-id-1234567890123456',
352351
spanId: 'previous-span-id',
@@ -365,7 +364,6 @@ describe('wrapMethodWithSentry', () => {
365364
options: {},
366365
context,
367366
startNewTrace: true,
368-
linkPreviousTrace: true,
369367
spanName: 'alarm',
370368
};
371369

@@ -399,7 +397,6 @@ describe('wrapMethodWithSentry', () => {
399397
options: {},
400398
context,
401399
startNewTrace: true,
402-
linkPreviousTrace: true,
403400
spanName: 'alarm',
404401
};
405402

@@ -423,7 +420,7 @@ describe('wrapMethodWithSentry', () => {
423420
);
424421
});
425422

426-
it('stores span context after execution when linkPreviousTrace is true', async () => {
423+
it('stores span context after execution when startNewTrace is true', async () => {
427424
vi.mocked(sentryCore.getActiveSpan).mockReturnValue({
428425
spanContext: vi.fn().mockReturnValue({
429426
traceId: 'current-trace-id-123456789012345678',
@@ -445,7 +442,6 @@ describe('wrapMethodWithSentry', () => {
445442
options: {},
446443
context,
447444
startNewTrace: true,
448-
linkPreviousTrace: true,
449445
spanName: 'alarm',
450446
};
451447

@@ -456,7 +452,7 @@ describe('wrapMethodWithSentry', () => {
456452
expect(mockStorage.put).toHaveBeenCalledWith('__SENTRY_TRACE_LINK__alarm', expect.any(Object));
457453
});
458454

459-
it('does not store span context when linkPreviousTrace is false', async () => {
455+
it('does not store span context when startNewTrace is false', async () => {
460456
vi.mocked(sentryCore.getActiveSpan).mockReturnValue({
461457
spanContext: vi.fn().mockReturnValue({
462458
traceId: 'current-trace-id-123456789012345678',
@@ -479,8 +475,7 @@ describe('wrapMethodWithSentry', () => {
479475
const options = {
480476
options: {},
481477
context,
482-
startNewTrace: true,
483-
linkPreviousTrace: false,
478+
startNewTrace: false,
484479
spanName: 'alarm',
485480
};
486481

@@ -490,7 +485,7 @@ describe('wrapMethodWithSentry', () => {
490485
// Wait for all waitUntil promises to resolve
491486
await Promise.all(waitUntilPromises);
492487

493-
// Should NOT store span context when linkPreviousTrace is false
488+
// Should NOT store span context when startNewTrace is false
494489
expect(mockStorage.put).not.toHaveBeenCalledWith('__SENTRY_TRACE_LINK__alarm', expect.any(Object));
495490
});
496491
});

0 commit comments

Comments
 (0)