Skip to content

Commit 21f06cf

Browse files
committed
switch to using global evt processor instead of async approach
1 parent f5d94c9 commit 21f06cf

File tree

2 files changed

+68
-28
lines changed

2 files changed

+68
-28
lines changed

packages/svelte/src/sdk.ts

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { addGlobalEventProcessor, BrowserOptions, init as browserInit, SDK_VERSION } from '@sentry/browser';
2-
import { getDomElement, SyncPromise } from '@sentry/utils';
2+
import type { EventProcessor } from '@sentry/types';
3+
import { getDomElement } from '@sentry/utils';
34
/**
45
* Inits the Svelte SDK
56
*/
@@ -18,29 +19,34 @@ export function init(options: BrowserOptions): void {
1819

1920
browserInit(options);
2021

21-
void detectAndReportSvelteKit();
22+
detectAndReportSvelteKit();
2223
}
2324

2425
/**
25-
* Detects if the SDK is initialized in a SvelteKit frontend, in which case
26-
* we add a global event processor to add it as an event.module entry to
27-
* outgoing events.
26+
* Adds a global event processor to detect if the SDK is initialized in a SvelteKit frontend,
27+
* in which case add SvelteKit an event.modules entry to outgoing events.
28+
* SvelteKit detection is performed only once, when the event processor is called for the
29+
* first time. We cannot perform this check upfront (directly when init is called) because
30+
* at this time, the HTML element might not yet be accessible.
2831
*/
29-
export function detectAndReportSvelteKit(): PromiseLike<void> {
30-
// We have to run this async because only after the SDK is initialized,
31-
// the HTML element is available
32-
return new SyncPromise(resolve => {
33-
if (isSvelteKitApp()) {
34-
addGlobalEventProcessor(event => {
35-
event.modules = {
36-
svelteKit: '1.0',
37-
...event.modules,
38-
};
39-
return event;
40-
});
32+
export function detectAndReportSvelteKit(): void {
33+
let detectedSvelteKit: boolean | undefined = undefined;
34+
35+
const svelteKitProcessor: EventProcessor = event => {
36+
if (detectedSvelteKit === undefined) {
37+
detectedSvelteKit = isSvelteKitApp();
38+
}
39+
if (detectedSvelteKit) {
40+
event.modules = {
41+
svelteKit: '1.0',
42+
...event.modules,
43+
};
4144
}
42-
resolve();
43-
});
45+
return event;
46+
};
47+
svelteKitProcessor.id = 'svelteKitProcessor';
48+
49+
addGlobalEventProcessor(svelteKitProcessor);
4450
}
4551

4652
/**
@@ -50,6 +56,6 @@ export function detectAndReportSvelteKit(): PromiseLike<void> {
5056
*
5157
* @see https://github.com/sveltejs/kit/issues/307 for more information
5258
*/
53-
function isSvelteKitApp(): boolean {
59+
export function isSvelteKitApp(): boolean {
5460
return getDomElement('div#svelte-announcer') !== null;
5561
}

packages/svelte/test/sdk.test.ts

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import { addGlobalEventProcessor, init as browserInitRaw, SDK_VERSION } from '@sentry/browser';
2+
import { EventProcessor } from '@sentry/types';
23

3-
import { detectAndReportSvelteKit, init as svelteInit } from '../src/sdk';
4+
import { detectAndReportSvelteKit, init as svelteInit, isSvelteKitApp } from '../src/sdk';
45

56
const browserInit = browserInitRaw as jest.Mock;
67
const addGlobalEventProcessorFunction = addGlobalEventProcessor as jest.Mock;
8+
let passedEventProcessor: EventProcessor | undefined;
9+
addGlobalEventProcessorFunction.mockImplementation(proc => {
10+
passedEventProcessor = proc;
11+
});
712

813
jest.mock('@sentry/browser');
914

@@ -33,23 +38,52 @@ describe('Initialize Svelte SDk', () => {
3338
});
3439

3540
describe('detectAndReportSvelteKit()', () => {
41+
const originalHtmlBody = document.body.innerHTML;
3642
afterEach(() => {
3743
jest.clearAllMocks();
44+
document.body.innerHTML = originalHtmlBody;
45+
passedEventProcessor = undefined;
3846
});
3947

40-
it('detects SvelteKit correctly and adds a global event processor', async () => {
41-
document.body.innerHTML += '<div id="svelte-announcer">Navigated to Home</div>';
42-
43-
await detectAndReportSvelteKit();
48+
it('registers a global event processor', async () => {
49+
detectAndReportSvelteKit();
4450

4551
expect(addGlobalEventProcessorFunction).toHaveBeenCalledTimes(1);
52+
expect(passedEventProcessor?.id).toEqual('svelteKitProcessor');
53+
});
54+
55+
it('adds "SvelteKit" as a module to the event, if SvelteKit was detected', () => {
56+
document.body.innerHTML += '<div id="svelte-announcer">Home</div>';
57+
detectAndReportSvelteKit();
58+
59+
const processedEvent = passedEventProcessor && passedEventProcessor({} as unknown as any, {});
60+
61+
expect(processedEvent).toBeDefined();
62+
expect(processedEvent).toEqual({ modules: { svelteKit: '1.0' } });
4663
});
4764

48-
it("doesn't add global event processor, if SvelteKit was not detected", async () => {
65+
it("doesn't add anything to the event, if SvelteKit was not detected", () => {
4966
document.body.innerHTML = '';
67+
detectAndReportSvelteKit();
5068

51-
await detectAndReportSvelteKit();
69+
const processedEvent = passedEventProcessor && passedEventProcessor({} as unknown as any, {});
5270

53-
expect(addGlobalEventProcessorFunction).not.toHaveBeenCalled();
71+
expect(processedEvent).toBeDefined();
72+
expect(processedEvent).toEqual({});
73+
});
74+
75+
describe('isSvelteKitApp()', () => {
76+
it('returns true if the svelte-announcer div is present', () => {
77+
document.body.innerHTML += '<div id="svelte-announcer">Home</div>';
78+
expect(isSvelteKitApp()).toBe(true);
79+
});
80+
it('returns false if the svelte-announcer div is not present (but similar elements)', () => {
81+
document.body.innerHTML += '<div id="svelte-something">Home</div>';
82+
expect(isSvelteKitApp()).toBe(false);
83+
});
84+
it('returns false if no div is present', () => {
85+
document.body.innerHTML = '';
86+
expect(isSvelteKitApp()).toBe(false);
87+
});
5488
});
5589
});

0 commit comments

Comments
 (0)