Skip to content

Commit 8b03e0b

Browse files
authored
fix(v8/feedback): Avoid lazy loading code for syncFeedbackIntegration (#14918)
Backport of #14895 for v8
1 parent 77cabfb commit 8b03e0b

File tree

2 files changed

+43
-44
lines changed

2 files changed

+43
-44
lines changed

packages/browser/src/feedbackSync.ts

-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@ import {
33
feedbackModalIntegration,
44
feedbackScreenshotIntegration,
55
} from '@sentry-internal/feedback';
6-
import { lazyLoadIntegration } from './utils/lazyLoadIntegration';
76

87
/** Add a widget to capture user feedback to your application. */
98
export const feedbackSyncIntegration = buildFeedbackIntegration({
10-
lazyLoadIntegration,
119
getModalIntegration: () => feedbackModalIntegration,
1210
getScreenshotIntegration: () => feedbackScreenshotIntegration,
1311
});

packages/feedback/src/core/integration.ts

+43-42
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type {
55
Integration,
66
IntegrationFn,
77
} from '@sentry/core';
8-
import { getClient, isBrowser, logger } from '@sentry/core';
8+
import { addIntegration, isBrowser, logger } from '@sentry/core';
99
import {
1010
ADD_SCREENSHOT_LABEL,
1111
CANCEL_BUTTON_LABEL,
@@ -39,16 +39,22 @@ type Unsubscribe = () => void;
3939
* Allow users to capture user feedback and send it to Sentry.
4040
*/
4141

42-
interface BuilderOptions {
43-
// The type here should be `keyof typeof LazyLoadableIntegrations`, but that'll cause a cicrular
44-
// dependency with @sentry/core
45-
lazyLoadIntegration: (
46-
name: 'feedbackModalIntegration' | 'feedbackScreenshotIntegration',
47-
scriptNonce?: string,
48-
) => Promise<IntegrationFn>;
49-
getModalIntegration?: null | (() => IntegrationFn);
50-
getScreenshotIntegration?: null | (() => IntegrationFn);
51-
}
42+
type BuilderOptions =
43+
| {
44+
lazyLoadIntegration?: never;
45+
getModalIntegration: () => IntegrationFn;
46+
getScreenshotIntegration: () => IntegrationFn;
47+
}
48+
| {
49+
// The type here should be `keyof typeof LazyLoadableIntegrations`, but that'll cause a cicrular
50+
// dependency with @sentry/core
51+
lazyLoadIntegration: (
52+
name: 'feedbackModalIntegration' | 'feedbackScreenshotIntegration',
53+
scriptNonce?: string,
54+
) => Promise<IntegrationFn>;
55+
getModalIntegration?: never;
56+
getScreenshotIntegration?: never;
57+
};
5258

5359
export const buildFeedbackIntegration = ({
5460
lazyLoadIntegration,
@@ -172,45 +178,40 @@ export const buildFeedbackIntegration = ({
172178
return _shadow as ShadowRoot;
173179
};
174180

175-
const _findIntegration = async <I extends Integration>(
176-
integrationName: string,
177-
getter: undefined | null | (() => IntegrationFn),
178-
functionMethodName: 'feedbackModalIntegration' | 'feedbackScreenshotIntegration',
179-
): Promise<I> => {
180-
const client = getClient();
181-
const existing = client && client.getIntegrationByName(integrationName);
182-
if (existing) {
183-
return existing as I;
184-
}
185-
const integrationFn = (getter && getter()) || (await lazyLoadIntegration(functionMethodName, scriptNonce));
186-
const integration = integrationFn();
187-
client && client.addIntegration(integration);
188-
return integration as I;
189-
};
190-
191181
const _loadAndRenderDialog = async (
192182
options: FeedbackInternalOptions,
193183
): Promise<ReturnType<FeedbackModalIntegration['createDialog']>> => {
194184
const screenshotRequired = options.enableScreenshot && isScreenshotSupported();
195-
const [modalIntegration, screenshotIntegration] = await Promise.all([
196-
_findIntegration<FeedbackModalIntegration>('FeedbackModal', getModalIntegration, 'feedbackModalIntegration'),
197-
screenshotRequired
198-
? _findIntegration<FeedbackScreenshotIntegration>(
199-
'FeedbackScreenshot',
200-
getScreenshotIntegration,
201-
'feedbackScreenshotIntegration',
202-
)
203-
: undefined,
204-
]);
205-
if (!modalIntegration) {
206-
// TODO: Let the end-user retry async loading
185+
186+
let modalIntegration: FeedbackModalIntegration;
187+
let screenshotIntegration: FeedbackScreenshotIntegration | undefined;
188+
189+
try {
190+
const modalIntegrationFn = getModalIntegration
191+
? getModalIntegration()
192+
: await lazyLoadIntegration('feedbackModalIntegration', scriptNonce);
193+
modalIntegration = modalIntegrationFn() as FeedbackModalIntegration;
194+
addIntegration(modalIntegration);
195+
} catch {
207196
DEBUG_BUILD &&
208197
logger.error(
209-
'[Feedback] Missing feedback modal integration. Try using `feedbackSyncIntegration` in your `Sentry.init`.',
198+
'[Feedback] Error when trying to load feedback integrations. Try using `feedbackSyncIntegration` in your `Sentry.init`.',
210199
);
211200
throw new Error('[Feedback] Missing feedback modal integration!');
212201
}
213-
if (screenshotRequired && !screenshotIntegration) {
202+
203+
try {
204+
const screenshotIntegrationFn = screenshotRequired
205+
? getScreenshotIntegration
206+
? getScreenshotIntegration()
207+
: await lazyLoadIntegration('feedbackScreenshotIntegration', scriptNonce)
208+
: undefined;
209+
210+
if (screenshotIntegrationFn) {
211+
screenshotIntegration = screenshotIntegrationFn() as FeedbackScreenshotIntegration;
212+
addIntegration(screenshotIntegration);
213+
}
214+
} catch {
214215
DEBUG_BUILD &&
215216
logger.error('[Feedback] Missing feedback screenshot integration. Proceeding without screenshots.');
216217
}
@@ -227,7 +228,7 @@ export const buildFeedbackIntegration = ({
227228
options.onFormSubmitted && options.onFormSubmitted();
228229
},
229230
},
230-
screenshotIntegration: screenshotRequired ? screenshotIntegration : undefined,
231+
screenshotIntegration,
231232
sendFeedback,
232233
shadow: _createShadow(options),
233234
});

0 commit comments

Comments
 (0)