-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathindex.ts
More file actions
131 lines (119 loc) · 4.41 KB
/
index.ts
File metadata and controls
131 lines (119 loc) · 4.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
* Welcome to Cloudflare Workers! This is your first worker.
*
* - Run `npm run dev` in your terminal to start a development server
* - Open a browser tab at http://localhost:8787/ to see your worker in action
* - Run `npm run deploy` to publish your worker
*
* Bind resources to your worker in `wrangler.toml`. After adding bindings, a type definition for the
* `Env` object can be regenerated with `npm run cf-typegen`.
*
* Learn more at https://developers.cloudflare.com/workers/
*/
import * as Sentry from '@sentry/cloudflare';
import { DurableObject } from 'cloudflare:workers';
class MyDurableObjectBase extends DurableObject<Env> {
private throwOnExit = new WeakMap<WebSocket, Error>();
async throwException(): Promise<void> {
throw new Error('Should be recorded in Sentry.');
}
async fetch(request: Request) {
const { pathname } = new URL(request.url);
switch (pathname) {
case '/throwException': {
await this.throwException();
break;
}
case '/ws':
const webSocketPair = new WebSocketPair();
const [client, server] = Object.values(webSocketPair);
this.ctx.acceptWebSocket(server);
return new Response(null, { status: 101, webSocket: client });
}
return new Response('DO is fine');
}
webSocketMessage(ws: WebSocket, message: string | ArrayBuffer): void | Promise<void> {
if (message === 'throwException') {
throw new Error('Should be recorded in Sentry: webSocketMessage');
} else if (message === 'throwOnExit') {
this.throwOnExit.set(ws, new Error('Should be recorded in Sentry: webSocketClose'));
}
}
webSocketClose(ws: WebSocket): void | Promise<void> {
if (this.throwOnExit.has(ws)) {
const error = this.throwOnExit.get(ws)!;
this.throwOnExit.delete(ws);
throw error;
}
}
}
export const MyDurableObject = Sentry.instrumentDurableObjectWithSentry(
(env: Env) => ({
dsn: env.E2E_TEST_DSN,
environment: 'qa', // dynamic sampling bias to keep transactions
tunnel: `http://localhost:3031/`, // proxy server
tracesSampleRate: 1.0,
sendDefaultPii: true,
transportOptions: {
// We are doing a lot of events at once in this test
bufferSize: 1000,
},
instrumentPrototypeMethods: true,
}),
MyDurableObjectBase,
);
export default Sentry.withSentry(
(env: Env) => ({
dsn: env.E2E_TEST_DSN,
environment: 'qa', // dynamic sampling bias to keep transactions
tunnel: `http://localhost:3031/`, // proxy server
tracesSampleRate: 1.0,
sendDefaultPii: true,
transportOptions: {
// We are doing a lot of events at once in this test
bufferSize: 1000,
},
}),
{
async fetch(request, env, ctx) {
const url = new URL(request.url);
switch (url.pathname) {
case '/rpc/throwException':
{
const id = env.MY_DURABLE_OBJECT.idFromName('foo');
const stub = env.MY_DURABLE_OBJECT.get(id) as DurableObjectStub<MyDurableObjectBase>;
try {
await stub.throwException();
} catch (e) {
//We will catch this to be sure not to log inside withSentry
return new Response(null, { status: 500 });
}
}
break;
case '/waitUntil':
console.log('waitUntil called');
const longRunningTask = async () => {
await new Promise(resolve => setTimeout(resolve, 2000));
console.log('ʕっ•ᴥ•ʔっ');
Sentry.captureException(new Error('ʕノ•ᴥ•ʔノ ︵ ┻━┻'));
return Sentry.startSpan({ name: 'longRunningTask' }, async () => {
await new Promise(resolve => setTimeout(resolve, 1000));
console.log(' /|\ ^._.^ /|\ ');
});
};
ctx.waitUntil(longRunningTask());
return new Response(null, { status: 200 });
case '/throwException':
throw new Error('To be recorded in Sentry.');
default:
if (url.pathname.startsWith('/pass-to-object/')) {
const id = env.MY_DURABLE_OBJECT.idFromName('foo');
const stub = env.MY_DURABLE_OBJECT.get(id) as DurableObjectStub<MyDurableObjectBase>;
url.pathname = url.pathname.replace('/pass-to-object/', '');
return stub.fetch(new Request(url, request));
}
}
return new Response('Hello World!');
},
} satisfies ExportedHandler<Env>,
);