Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e8d255f

Browse files
authored
Revert "feat(cloudflare): Introduce lock instrumentation for context.waitUntil to prevent multiple instrumentation (#17539)" (#17666)
This PR reverts #17539 because it causes e2e test fails on PRs as well as on `develop` and release branches. It seems like when our e2e tests expect errors in websocket, another unrelated error is thrown: ``` ✘ 5 [chromium] › tests/index.test.ts:41:5 › Websocket.webSocketMessage (13ms) [WebServer] ✘ [ERROR] Uncaught TypeError: Illegal invocation: function called with incorrect `this` reference. See https://developers.cloudflare.com/workers/observability/errors/#illegal-invocation-errors for details. Error [WebServer] [WebServer] at fetch (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/src/index.ts:32:18) [WebServer] at null.<anonymous> (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+cloudflare@10.11.0_@cloudflare+workers-types@4.20250913.0/node_modules/@sentry/cloudflare/src/durableobject.ts:219:23) [WebServer] at null.<anonymous> (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+cloudflare@10.11.0_@cloudflare+workers-types@4.20250913.0/node_modules/@sentry/cloudflare/src/request.ts:108:33) [WebServer] at handleCallbackErrors.status.status (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+core@10.11.0/node_modules/@sentry/core/src/tracing/trace.ts:77:15) [WebServer] at handleCallbackErrors (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+core@10.11.0/node_modules/@sentry/core/src/utils/handleCallbackErrors.ts:20:26) [WebServer] at null.<anonymous> (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+core@10.11.0/node_modules/@sentry/core/src/tracing/trace.ts:76:14) [WebServer] at null.<anonymous> (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+core@10.11.0/node_modules/@sentry/core/src/tracing/trace.ts:530:100) [WebServer] at null.<anonymous> (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+core@10.11.0/node_modules/@sentry/core/src/tracing/trace.ts:60:12) [WebServer] at null.<anonymous> (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+cloudflare@10.11.0_@cloudflare+workers-types@4.20250913.0/node_modules/@sentry/cloudflare/src/async.ts:41:14) [WebServer] at withScope (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+cloudflare@10.11.0_@cloudflare+workers-types@4.20250913.0/node_modules/@sentry/cloudflare/src/async.ts:40:25) [WebServer] at withScope (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+core@10.11.0/node_modules/@sentry/core/src/currentScopes.ts:59:18) [WebServer] at startSpan (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+core@10.11.0/node_modules/@sentry/core/src/tracing/trace.ts:56:10) [WebServer] at null.<anonymous> (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+cloudflare@10.11.0_@cloudflare+workers-types@4.20250913.0/node_modules/@sentry/cloudflare/src/request.ts:101:16) [WebServer] at null.<anonymous> (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+core@10.11.0/node_modules/@sentry/core/src/tracing/trace.ts:229:12) [WebServer] at null.<anonymous> (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+cloudflare@10.11.0_@cloudflare+workers-types@4.20250913.0/node_modules/@sentry/cloudflare/src/async.ts:41:14) [WebServer] at withScope (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+cloudflare@10.11.0_@cloudflare+workers-types@4.20250913.0/node_modules/@sentry/cloudflare/src/async.ts:40:25) [WebServer] at withScope (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+core@10.11.0/node_modules/@sentry/core/src/currentScopes.ts:65:14) [WebServer] at continueTrace (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+core@10.11.0/node_modules/@sentry/core/src/tracing/trace.ts:226:10) [WebServer] at null.<anonymous> (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+cloudflare@10.11.0_@cloudflare+workers-types@4.20250913.0/node_modules/@sentry/cloudflare/src/request.ts:95:12) [WebServer] at null.<anonymous> (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+cloudflare@10.11.0_@cloudflare+workers-types@4.20250913.0/node_modules/@sentry/cloudflare/src/async.ts:56:14) [WebServer] at withIsolationScope (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+cloudflare@10.11.0_@cloudflare+workers-types@4.20250913.0/node_modules/@sentry/cloudflare/src/async.ts:55:25) [WebServer] at withIsolationScope (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+core@10.11.0/node_modules/@sentry/core/src/currentScopes.ts:114:14) [WebServer] at wrapRequestHandler (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+cloudflare@10.11.0_@cloudflare+workers-types@4.20250913.0/node_modules/@sentry/cloudflare/src/request.ts:43:10) [WebServer] at apply (file:///private/var/folders/63/gxb4ks2n7wbf_7bbwz86cgsc0000gn/T/sentry-e2e-tests-cloudflare-workers-fU9D9e/node_modules/.pnpm/@sentry+cloudflare@10.11.0_@cloudflare+workers-types@4.20250913.0/node_modules/@sentry/cloudflare/src/durableobject.ts:218:20) [WebServer] [WebServer] ``` The SDK catches this error instead but the tests fail because they expect the other error. Not sure what in #17539 caused this but for now let's unblock ourselves first and follow up with a fix in a new attempt (cc @0xbad0c0d3 )
1 parent 57b0656 commit e8d255f

File tree

15 files changed

+162
-302
lines changed

15 files changed

+162
-302
lines changed

‎dev-packages/e2e-tests/test-applications/cloudflare-workers/tests/index.test.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ test("Request processed by DurableObject's fetch is recorded", async ({ baseURL
4040

4141
test('Websocket.webSocketMessage', async ({ baseURL }) => {
4242
const eventWaiter = waitForError('cloudflare-workers', event => {
43-
return event.exception?.values?.[0]?.mechanism?.type==='auto.faas.cloudflare.durable_object';
43+
return !!event.exception?.values?.[0];
4444
});
4545
const url = new URL('/pass-to-object/ws', baseURL);
4646
url.protocol = url.protocol.replace('http', 'ws');
@@ -51,11 +51,12 @@ test('Websocket.webSocketMessage', async ({ baseURL }) => {
5151
const event = await eventWaiter;
5252
socket.close();
5353
expect(event.exception?.values?.[0]?.value).toBe('Should be recorded in Sentry: webSocketMessage');
54+
expect(event.exception?.values?.[0]?.mechanism?.type).toBe('auto.faas.cloudflare.durable_object');
5455
});
5556

5657
test('Websocket.webSocketClose', async ({ baseURL }) => {
5758
const eventWaiter = waitForError('cloudflare-workers', event => {
58-
return event.exception?.values?.[0]?.mechanism?.type==='auto.faas.cloudflare.durable_object';
59+
return !!event.exception?.values?.[0];
5960
});
6061
const url = new URL('/pass-to-object/ws', baseURL);
6162
url.protocol = url.protocol.replace('http', 'ws');
@@ -66,4 +67,5 @@ test('Websocket.webSocketClose', async ({ baseURL }) => {
6667
});
6768
const event = await eventWaiter;
6869
expect(event.exception?.values?.[0]?.value).toBe('Should be recorded in Sentry: webSocketClose');
70+
expect(event.exception?.values?.[0]?.mechanism?.type).toBe('auto.faas.cloudflare.durable_object');
6971
});

‎packages/cloudflare/src/client.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { ClientOptions, Options, ServerRuntimeClientOptions } from '@sentry/core';
22
import { applySdkMetadata, ServerRuntimeClient } from '@sentry/core';
3+
import type { makeFlushLock } from './flush';
34
import type { CloudflareTransportOptions } from './transport';
4-
import type { makeFlushLock } from './utils/flushLock';
55

66
/**
77
* The Sentry Cloudflare SDK Client.

‎packages/cloudflare/src/durableobject.ts‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import { isInstrumented, markAsInstrumented } from './instrument';
1818
import { getFinalOptions } from './options';
1919
import { wrapRequestHandler } from './request';
2020
import { init } from './sdk';
21-
import { copyExecutionContext } from './utils/copyExecutionContext';
2221

2322
type MethodWrapperOptions = {
2423
spanName?: string;
@@ -193,11 +192,9 @@ export function instrumentDurableObjectWithSentry<
193192
C extends new (state: DurableObjectState, env: E) => T,
194193
>(optionsCallback: (env: E) => CloudflareOptions, DurableObjectClass: C): C {
195194
return new Proxy(DurableObjectClass, {
196-
construct(target, [ctx, env]) {
195+
construct(target, [context, env]) {
197196
setAsyncLocalStorageAsyncContextStrategy();
198197

199-
const context = copyExecutionContext(ctx);
200-
201198
const options = getFinalOptions(optionsCallback(env), env);
202199

203200
const obj = new target(context, env);

‎packages/cloudflare/src/flush.ts‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import type { ExecutionContext } from '@cloudflare/workers-types';
2+
3+
type FlushLock = {
4+
readonly ready: Promise<void>;
5+
readonly finalize: () => Promise<void>;
6+
};
7+
8+
/**
9+
* Enhances the given execution context by wrapping its `waitUntil` method with a proxy
10+
* to monitor pending tasks, and provides a flusher function to ensure all tasks
11+
* have been completed before executing any subsequent logic.
12+
*
13+
* @param {ExecutionContext} context - The execution context to be enhanced. If no context is provided, the function returns undefined.
14+
* @return {FlushLock} Returns a flusher function if a valid context is provided, otherwise undefined.
15+
*/
16+
export function makeFlushLock(context: ExecutionContext): FlushLock {
17+
let resolveAllDone: () => void = () => undefined;
18+
const allDone = new Promise<void>(res => {
19+
resolveAllDone = res;
20+
});
21+
let pending = 0;
22+
const originalWaitUntil = context.waitUntil.bind(context) as typeof context.waitUntil;
23+
context.waitUntil = promise => {
24+
pending++;
25+
return originalWaitUntil(
26+
promise.finally(() => {
27+
if (--pending === 0) resolveAllDone();
28+
}),
29+
);
30+
};
31+
return Object.freeze({
32+
ready: allDone,
33+
finalize: () => {
34+
if (pending === 0) resolveAllDone();
35+
return allDone;
36+
},
37+
});
38+
}

‎packages/cloudflare/src/handler.ts‎

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import { getFinalOptions } from './options';
1414
import { wrapRequestHandler } from './request';
1515
import { addCloudResourceContext } from './scope-utils';
1616
import { init } from './sdk';
17-
import { copyExecutionContext } from './utils/copyExecutionContext';
1817

1918
/**
2019
* Wrapper for Cloudflare handlers.
@@ -38,11 +37,9 @@ export function withSentry<Env = unknown, QueueHandlerMessage = unknown, CfHostM
3837
if ('fetch' in handler && typeof handler.fetch === 'function' && !isInstrumented(handler.fetch)) {
3938
handler.fetch = new Proxy(handler.fetch, {
4039
apply(target, thisArg, args: Parameters<ExportedHandlerFetchHandler<Env, CfHostMetadata>>) {
41-
const [request, env, ctx] = args;
40+
const [request, env, context] = args;
4241

4342
const options = getFinalOptions(optionsCallback(env), env);
44-
const context = copyExecutionContext(ctx);
45-
args[2] = context;
4643

4744
return wrapRequestHandler({ options, request, context }, () => target.apply(thisArg, args));
4845
},
@@ -74,9 +71,7 @@ export function withSentry<Env = unknown, QueueHandlerMessage = unknown, CfHostM
7471
if ('scheduled' in handler && typeof handler.scheduled === 'function' && !isInstrumented(handler.scheduled)) {
7572
handler.scheduled = new Proxy(handler.scheduled, {
7673
apply(target, thisArg, args: Parameters<ExportedHandlerScheduledHandler<Env>>) {
77-
const [event, env, ctx] = args;
78-
const context = copyExecutionContext(ctx);
79-
args[2] = context;
74+
const [event, env, context] = args;
8075
return withIsolationScope(isolationScope => {
8176
const options = getFinalOptions(optionsCallback(env), env);
8277
const waitUntil = context.waitUntil.bind(context);
@@ -119,9 +114,7 @@ export function withSentry<Env = unknown, QueueHandlerMessage = unknown, CfHostM
119114
if ('email' in handler && typeof handler.email === 'function' && !isInstrumented(handler.email)) {
120115
handler.email = new Proxy(handler.email, {
121116
apply(target, thisArg, args: Parameters<EmailExportedHandler<Env>>) {
122-
const [emailMessage, env, ctx] = args;
123-
const context = copyExecutionContext(ctx);
124-
args[2] = context;
117+
const [emailMessage, env, context] = args;
125118
return withIsolationScope(isolationScope => {
126119
const options = getFinalOptions(optionsCallback(env), env);
127120
const waitUntil = context.waitUntil.bind(context);
@@ -162,9 +155,7 @@ export function withSentry<Env = unknown, QueueHandlerMessage = unknown, CfHostM
162155
if ('queue' in handler && typeof handler.queue === 'function' && !isInstrumented(handler.queue)) {
163156
handler.queue = new Proxy(handler.queue, {
164157
apply(target, thisArg, args: Parameters<ExportedHandlerQueueHandler<Env, QueueHandlerMessage>>) {
165-
const [batch, env, ctx] = args;
166-
const context = copyExecutionContext(ctx);
167-
args[2] = context;
158+
const [batch, env, context] = args;
168159

169160
return withIsolationScope(isolationScope => {
170161
const options = getFinalOptions(optionsCallback(env), env);
@@ -214,9 +205,7 @@ export function withSentry<Env = unknown, QueueHandlerMessage = unknown, CfHostM
214205
if ('tail' in handler && typeof handler.tail === 'function' && !isInstrumented(handler.tail)) {
215206
handler.tail = new Proxy(handler.tail, {
216207
apply(target, thisArg, args: Parameters<ExportedHandlerTailHandler<Env>>) {
217-
const [, env, ctx] = args;
218-
const context = copyExecutionContext(ctx);
219-
args[2] = context;
208+
const [, env, context] = args;
220209

221210
return withIsolationScope(async isolationScope => {
222211
const options = getFinalOptions(optionsCallback(env), env);

‎packages/cloudflare/src/sdk.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import {
1212
} from '@sentry/core';
1313
import type { CloudflareClientOptions, CloudflareOptions } from './client';
1414
import { CloudflareClient } from './client';
15+
import { makeFlushLock } from './flush';
1516
import { fetchIntegration } from './integrations/fetch';
1617
import { setupOpenTelemetryTracer } from './opentelemetry/tracer';
1718
import { makeCloudflareTransport } from './transport';
18-
import { makeFlushLock } from './utils/flushLock';
1919
import { defaultStackParser } from './vendor/stacktrace';
2020

2121
/** Get the default integrations for the Cloudflare SDK. */

‎packages/cloudflare/src/utils/copyExecutionContext.ts‎

Lines changed: 0 additions & 47 deletions
This file was deleted.

‎packages/cloudflare/src/utils/flushLock.ts‎

Lines changed: 0 additions & 57 deletions
This file was deleted.

‎packages/cloudflare/src/utils/makePromiseResolver.ts‎

Lines changed: 0 additions & 26 deletions
This file was deleted.

‎packages/cloudflare/test/copy-execution-context.test.ts‎

Lines changed: 0 additions & 47 deletions
This file was deleted.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /