Skip to content

Commit d9260cf

Browse files
authored
fix(node): Check for res.end before passing to Proxy (#15776)
1 parent 3d63621 commit d9260cf

File tree

1 file changed

+45
-41
lines changed

1 file changed

+45
-41
lines changed

packages/node/src/integrations/http/SentryHttpInstrumentationBeforeOtel.ts

+45-41
Original file line numberDiff line numberDiff line change
@@ -70,46 +70,50 @@ export class SentryHttpInstrumentationBeforeOtel extends InstrumentationBase {
7070
function patchResponseToFlushOnServerlessPlatforms(res: http.OutgoingMessage): void {
7171
// Freely extend this function with other platforms if necessary
7272
if (process.env.VERCEL) {
73-
let markOnEndDone = (): void => undefined;
74-
const onEndDonePromise = new Promise<void>(res => {
75-
markOnEndDone = res;
76-
});
77-
78-
res.on('close', () => {
79-
markOnEndDone();
80-
});
81-
82-
// eslint-disable-next-line @typescript-eslint/unbound-method
83-
res.end = new Proxy(res.end, {
84-
apply(target, thisArg, argArray) {
85-
vercelWaitUntil(
86-
new Promise<void>(finishWaitUntil => {
87-
// Define a timeout that unblocks the lambda just to be safe so we're not indefinitely keeping it alive, exploding server bills
88-
const timeout = setTimeout(() => {
89-
finishWaitUntil();
90-
}, 2000);
91-
92-
onEndDonePromise
93-
.then(() => {
94-
DEBUG_BUILD && logger.log('Flushing events before Vercel Lambda freeze');
95-
return flush(2000);
96-
})
97-
.then(
98-
() => {
99-
clearTimeout(timeout);
100-
finishWaitUntil();
101-
},
102-
e => {
103-
clearTimeout(timeout);
104-
DEBUG_BUILD && logger.log('Error while flushing events for Vercel:\n', e);
105-
finishWaitUntil();
106-
},
107-
);
108-
}),
109-
);
110-
111-
return target.apply(thisArg, argArray);
112-
},
113-
});
73+
// In some cases res.end does not seem to be defined leading to errors if passed to Proxy
74+
// https://github.com/getsentry/sentry-javascript/issues/15759
75+
if (typeof res.end === 'function') {
76+
let markOnEndDone = (): void => undefined;
77+
const onEndDonePromise = new Promise<void>(res => {
78+
markOnEndDone = res;
79+
});
80+
81+
res.on('close', () => {
82+
markOnEndDone();
83+
});
84+
85+
// eslint-disable-next-line @typescript-eslint/unbound-method
86+
res.end = new Proxy(res.end, {
87+
apply(target, thisArg, argArray) {
88+
vercelWaitUntil(
89+
new Promise<void>(finishWaitUntil => {
90+
// Define a timeout that unblocks the lambda just to be safe so we're not indefinitely keeping it alive, exploding server bills
91+
const timeout = setTimeout(() => {
92+
finishWaitUntil();
93+
}, 2000);
94+
95+
onEndDonePromise
96+
.then(() => {
97+
DEBUG_BUILD && logger.log('Flushing events before Vercel Lambda freeze');
98+
return flush(2000);
99+
})
100+
.then(
101+
() => {
102+
clearTimeout(timeout);
103+
finishWaitUntil();
104+
},
105+
e => {
106+
clearTimeout(timeout);
107+
DEBUG_BUILD && logger.log('Error while flushing events for Vercel:\n', e);
108+
finishWaitUntil();
109+
},
110+
);
111+
}),
112+
);
113+
114+
return target.apply(thisArg, argArray);
115+
},
116+
});
117+
}
114118
}
115119
}

0 commit comments

Comments
 (0)