-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Labels
Package: nextjsIssues related to the Sentry Nextjs SDKIssues related to the Sentry Nextjs SDK
Description
Is there an existing issue for this?
- I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
- I have reviewed the documentation https://docs.sentry.io/
- I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases
How do you use Sentry?
Self-hosted/on-premise
Which SDK are you using?
@sentry/nextjs
SDK Version
8.30.0
Framework Version
next 14.2.13, react 18.2.0, video.js 7.21.1
Link to Sentry event
No response
Reproduction Example/SDK Setup
// next.config.js
const { withSentryConfig } = require('@sentry/nextjs');
module.exports = withSentryConfig(bundledConfig, {
org: 'xxx',
project: 'xxx',
sentryUrl: 'https://xxx/',
silent: !process.env.CI,
widenClientFileUpload: true,
reactComponentAnnotation: {
enabled: false,
},
tunnelRoute: '/monitoring',
hideSourceMaps: false,
disableLogger: true,
automaticVercelMonitors: true,
});
// sentry.client.config.ts
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: 'https://xxx',
integrations: [Sentry.replayIntegration()],
tracesSampleRate: 1,
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
debug: true,
});
// sentry.edge.config.ts
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: 'https://xxx',
tracesSampleRate: 1,
debug: false,
});
// sentry.server.config.ts
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: 'https://xxx',
tracesSampleRate: 1,
debug: false,
});
Steps to Reproduce
- Play an endless live stream (CCTV in FLV format).
- Memory usage keeps increasing over time.
Expected Result
I believe this is causing the issue:
Unresolved promises and their context are stacking up in the task queue.
// sentry-javascript/packages/utils/src/instrument/fetch.ts
async function resolveResponse(res: Response | undefined, onFinishedResolving: () => void): Promise<void> {
if (res && res.body && res.body.getReader) {
const responseReader = res.body.getReader();
// eslint-disable-next-line no-inner-declarations
async function consumeChunks({ done }: { done: boolean }): Promise<void> {
if (!done) {
try {
// abort reading if read op takes more than 5s
const result = await Promise.race([
responseReader.read(),
new Promise<{ done: boolean }>(res => {
setTimeout(() => {
res({ done: true });
}, 5000);
}),
]);
await consumeChunks(result);
} catch (error) {
// handle error if needed
}
} else {
return Promise.resolve();
}
}
return responseReader
.read()
.then(consumeChunks)
.then(onFinishedResolving)
.catch(() => undefined);
}
}
Is there any specific reason to use recursion in this case? If not, may I submit a PR with an alternative approach?
example:
async function resolveResponse(res, onFinishedResolving) {
if (!res?.body?.getReader) return;
const responseReader = res.body.getReader();
while (true) {
try {
const { done } = await Promise.race([
responseReader.read(),
new Promise((resolve) => setTimeout(() => resolve({ done: true }), 5000)),
]);
if (done) break;
} catch (error) {
// handle error if needed
break;
}
}
responseReader.releaseLock();
onFinishedResolving();
}
Actual Result
Metadata
Metadata
Assignees
Labels
Package: nextjsIssues related to the Sentry Nextjs SDKIssues related to the Sentry Nextjs SDK
Type
Projects
Status
No status