Skip to content

Commit 13cb2b5

Browse files
authored
Merge branch 'v9' into cg-v9backport-rr-createsenrtyhandleerror
2 parents 42b6522 + c58e1c6 commit 13cb2b5

File tree

7 files changed

+30
-22
lines changed

7 files changed

+30
-22
lines changed

dev-packages/browser-integration-tests/suites/replay/autoFlushOnFeedback/init.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ window.Replay = Sentry.replayIntegration({
55
flushMinDelay: 200,
66
flushMaxDelay: 200,
77
useCompression: false,
8-
_experiments: {
9-
autoFlushOnFeedback: true,
10-
},
118
});
129

1310
Sentry.init({

dev-packages/e2e-tests/test-applications/nextjs-14/tests/generation-functions.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,17 @@ test('Should send a transaction and an error event for a faulty generateMetadata
4242
});
4343

4444
const errorEventPromise = waitForError('nextjs-14', errorEvent => {
45-
return errorEvent?.exception?.values?.[0]?.value === 'generateMetadata Error';
45+
return (
46+
errorEvent?.exception?.values?.[0]?.value === 'generateMetadata Error' &&
47+
errorEvent.transaction === 'Page.generateMetadata (/generation-functions)'
48+
);
4649
});
4750

4851
await page.goto(`/generation-functions?metadataTitle=${testTitle}&shouldThrowInGenerateMetadata=1`);
4952

5053
const errorEvent = await errorEventPromise;
5154
const transactionEvent = await transactionPromise;
5255

53-
expect(errorEvent.transaction).toBe('Page.generateMetadata (/generation-functions)');
54-
5556
// Assert that isolation scope works properly
5657
expect(errorEvent.tags?.['my-isolated-tag']).toBe(true);
5758
expect(errorEvent.tags?.['my-global-scope-isolated-tag']).not.toBeDefined();

packages/nextjs/src/common/wrapRouteHandlerWithSentry.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ import {
1212
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
1313
setCapturedScopesOnSpan,
1414
setHttpStatus,
15+
vercelWaitUntil,
1516
winterCGHeadersToDict,
1617
withIsolationScope,
1718
withScope,
1819
} from '@sentry/core';
1920
import { isNotFoundNavigationError, isRedirectNavigationError } from './nextNavigationErrorUtils';
2021
import type { RouteHandlerContext } from './types';
22+
import { flushSafelyWithTimeout } from './utils/responseEnd';
2123
import { commonObjectToIsolationScope } from './utils/tracingUtils';
2224

2325
/**
@@ -92,6 +94,9 @@ export function wrapRouteHandlerWithSentry<F extends (...args: any[]) => any>(
9294
});
9395
}
9496
},
97+
() => {
98+
vercelWaitUntil(flushSafelyWithTimeout());
99+
},
95100
);
96101

97102
try {

packages/node/src/integrations/tracing/openai/instrumentation.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,19 @@ export class SentryOpenAiInstrumentation extends InstrumentationBase<Instrumenta
8383
}
8484
}
8585

86-
const isESM = Object.prototype.toString.call(exports) === '[object Module]';
87-
if (isESM) {
86+
// Constructor replacement - handle read-only properties
87+
// The OpenAI property might have only a getter, so use defineProperty
88+
try {
8889
exports.OpenAI = WrappedOpenAI;
89-
return exports;
90+
} catch (error) {
91+
// If direct assignment fails, override the property descriptor
92+
Object.defineProperty(exports, 'OpenAI', {
93+
value: WrappedOpenAI,
94+
writable: true,
95+
configurable: true,
96+
enumerable: true,
97+
});
9098
}
91-
92-
return { ...exports, OpenAI: WrappedOpenAI };
99+
return exports;
93100
}
94101
}

packages/replay-internal/src/replay.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,7 @@ export class ReplayContainer implements ReplayContainerInterface {
939939

940940
// There is no way to remove these listeners, so ensure they are only added once
941941
if (!this._hasInitializedCoreListeners) {
942-
addGlobalListeners(this, { autoFlushOnFeedback: this._options._experiments.autoFlushOnFeedback });
942+
addGlobalListeners(this);
943943

944944
this._hasInitializedCoreListeners = true;
945945
}

packages/replay-internal/src/types/replay.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ export interface ReplayPluginOptions extends ReplayNetworkOptions {
235235
* https://github.com/rrweb-io/rrweb/blob/master/docs/recipes/cross-origin-iframes.md#considerations
236236
*/
237237
recordCrossOriginIframes: boolean;
238+
/**
239+
* @deprecated This option is now the default behavior and the option is no longer needed. It will be removed in the next major version.
240+
*/
238241
autoFlushOnFeedback: boolean;
239242
/**
240243
* Completetly ignore mutations matching the given selectors.

packages/replay-internal/src/util/addGlobalListeners.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@ import type { ReplayContainer } from '../types';
1616
/**
1717
* Add global listeners that cannot be removed.
1818
*/
19-
export function addGlobalListeners(
20-
replay: ReplayContainer,
21-
{ autoFlushOnFeedback }: { autoFlushOnFeedback?: boolean },
22-
): void {
19+
export function addGlobalListeners(replay: ReplayContainer): void {
2320
// Listeners from core SDK //
2421
const client = getClient();
2522

@@ -64,17 +61,15 @@ export function addGlobalListeners(
6461
const replayId = replay.getSessionId();
6562
if (options?.includeReplay && replay.isEnabled() && replayId && feedbackEvent.contexts?.feedback) {
6663
// In case the feedback is sent via API and not through our widget, we want to flush replay
67-
if (feedbackEvent.contexts.feedback.source === 'api' && autoFlushOnFeedback) {
64+
if (feedbackEvent.contexts.feedback.source === 'api') {
6865
await replay.flush();
6966
}
7067
feedbackEvent.contexts.feedback.replay_id = replayId;
7168
}
7269
});
7370

74-
if (autoFlushOnFeedback) {
75-
client.on('openFeedbackWidget', async () => {
76-
await replay.flush();
77-
});
78-
}
71+
client.on('openFeedbackWidget', async () => {
72+
await replay.flush();
73+
});
7974
}
8075
}

0 commit comments

Comments
 (0)