|
1 | 1 | import type { IntegrationFn } from '@sentry/core'; |
2 | | -import { defineIntegration } from '@sentry/core'; |
| 2 | +import { debug, defineIntegration } from '@sentry/core'; |
3 | 3 | import { setAsyncLocalStorageAsyncContextStrategy } from '../async'; |
4 | 4 | import type { RequestHandlerWrapperOptions } from '../wrap-deno-request-handler'; |
5 | 5 | import { wrapDenoRequestHandler } from '../wrap-deno-request-handler'; |
@@ -44,24 +44,44 @@ const applyHandlerWrap = <A extends Deno.Addr>( |
44 | 44 | () => handler(request, info as Deno.ServeHandlerInfo<A>), |
45 | 45 | )) as Deno.ServeHandler; |
46 | 46 |
|
| 47 | +const instrumentedDenoServe = (serve: typeof Deno.serve): typeof Deno.serve => |
| 48 | + new Proxy(serve, { |
| 49 | + apply(target, thisArg, args: ServeParams) { |
| 50 | + if (isSimpleHandler(args)) { |
| 51 | + args[0] = applyHandlerWrap(args[0]); |
| 52 | + } else if (isServeOptWithFunction(args)) { |
| 53 | + args[1] = applyHandlerWrap(args[1], args[0]); |
| 54 | + } else if (isServeInitOptions(args)) { |
| 55 | + args[0].handler = applyHandlerWrap(args[0].handler, args[0]); |
| 56 | + } |
| 57 | + // if none of those matched, it'll crash, most likely. |
| 58 | + return target.apply(thisArg, args); |
| 59 | + }, |
| 60 | + }); |
| 61 | + |
47 | 62 | const _denoServeIntegration = (() => { |
48 | 63 | return { |
49 | 64 | name: INTEGRATION_NAME, |
50 | 65 | setupOnce() { |
51 | 66 | setAsyncLocalStorageAsyncContextStrategy(); |
52 | | - Deno.serve = new Proxy(Deno.serve, { |
53 | | - apply(target, thisArg, args: ServeParams) { |
54 | | - if (isSimpleHandler(args)) { |
55 | | - args[0] = applyHandlerWrap(args[0]); |
56 | | - } else if (isServeOptWithFunction(args)) { |
57 | | - args[1] = applyHandlerWrap(args[1], args[0]); |
58 | | - } else if (isServeInitOptions(args)) { |
59 | | - args[0].handler = applyHandlerWrap(args[0].handler, args[0]); |
60 | | - } |
61 | | - // if none of those matched, it'll crash, most likely. |
62 | | - return target.apply(thisArg, args); |
63 | | - }, |
64 | | - }); |
| 67 | + |
| 68 | + const originalServe = Deno.serve; |
| 69 | + const wrappedServe = instrumentedDenoServe(originalServe); |
| 70 | + |
| 71 | + try { |
| 72 | + const descriptor = Object.getOwnPropertyDescriptor(Deno, 'serve'); |
| 73 | + |
| 74 | + Object.defineProperty(Deno, 'serve', { |
| 75 | + configurable: descriptor?.configurable ?? true, |
| 76 | + enumerable: descriptor?.enumerable ?? true, |
| 77 | + // writable: true avoids other instrumentations on older Deno versions |
| 78 | + // from crashing if they used to do assignment |
| 79 | + writable: true, |
| 80 | + value: wrappedServe, |
| 81 | + }); |
| 82 | + } catch (error) { |
| 83 | + debug.warn('Could not instrument Deno.serve.', error); |
| 84 | + } |
65 | 85 | }, |
66 | 86 | }; |
67 | 87 | }) satisfies IntegrationFn; |
|
0 commit comments