Skip to content

Commit 0f3e994

Browse files
rytkhsclaude
andcommitted
fix(cloudflare): Bind non-instrumented Queue methods to the underlying binding
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 8b31bf1 commit 0f3e994

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

‎packages/cloudflare/src/instrumentations/worker/instrumentQueueProducer.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ export function instrumentQueueProducer<T extends Queue>(queue: T, bindingName:
9999
};
100100
}
101101

102-
return Reflect.get(target, prop, receiver);
102+
const value = Reflect.get(target, prop, receiver) as unknown;
103+
104+
return typeof value === 'function' ? value.bind(target) : value;
103105
},
104106
});
105107
}

‎packages/cloudflare/test/instrumentations/worker/instrumentQueueProducer.test.ts‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Queue } from '@cloudflare/workers-types';
1+
import type { Queue, QueueMetrics } from '@cloudflare/workers-types';
22
import * as SentryCore from '@sentry/core';
33
import { beforeEach, describe, expect, test, vi } from 'vitest';
44
import { instrumentQueueProducer } from '../../../src/instrumentations/worker/instrumentQueueProducer';
@@ -10,6 +10,15 @@ function createMockQueue(): Queue {
1010
} as unknown as Queue;
1111
}
1212

13+
// `metrics()` reads a private field, so it throws when `this` is the Proxy, as workerd's native methods do.
14+
class BrandCheckedQueue {
15+
readonly #metrics: QueueMetrics = { backlogCount: 3, backlogBytes: 2048 };
16+
17+
public metrics(): Promise<QueueMetrics> {
18+
return Promise.resolve(this.#metrics);
19+
}
20+
}
21+
1322
describe('instrumentQueueProducer', () => {
1423
beforeEach(() => {
1524
vi.clearAllMocks();
@@ -178,4 +187,13 @@ describe('instrumentQueueProducer', () => {
178187
const wrapped = instrumentQueueProducer(queue, 'MY_QUEUE') as Queue & { customMethod: () => string };
179188
expect(wrapped.customMethod()).toBe('hi');
180189
});
190+
191+
test('calls non-instrumented methods on the underlying queue', async () => {
192+
const queue = new BrandCheckedQueue() as unknown as Queue;
193+
const wrapped = instrumentQueueProducer(queue, 'MY_QUEUE');
194+
195+
const metrics = await wrapped.metrics();
196+
197+
expect(metrics).toEqual({ backlogCount: 3, backlogBytes: 2048 });
198+
});
181199
});

0 commit comments

Comments
 (0)