Skip to content

Commit f0e5e0a

Browse files
committed
feat(solidjs): Add withSentryErrorBoundary HOC
1 parent 691e5de commit f0e5e0a

File tree

13 files changed

+2022
-3
lines changed

13 files changed

+2022
-3
lines changed

dev-packages/e2e-tests/test-applications/solidjs/src/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import PageRoot from './pageroot';
77
import { routes } from './routes';
88

99
Sentry.init({
10-
dsn: import.meta.env.PUBLIC_E2E_TEST_DSN,
10+
dsn:
11+
import.meta.env.PUBLIC_E2E_TEST_DSN ||
12+
'https://3b6c388182fb435097f41d181be2b2ba@o4504321058471936.ingest.sentry.io/4504321066008576',
1113
debug: true,
1214
environment: 'qa', // dynamic sampling bias to keep transactions
1315
integrations: [Sentry.solidRouterBrowserTracingIntegration({ useBeforeLeave, useLocation })],

dev-packages/e2e-tests/test-applications/solidjs/src/pageroot.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ export default function PageRoot(props) {
1010
Home
1111
</A>
1212
</li>
13+
<li>
14+
<A href="/error-boundary-example" class="no-underline hover:underline">
15+
Error Boundary Example
16+
</A>
17+
</li>
1318
<li class="py-2 px-4">
1419
<A href="/error" class="no-underline hover:underline">
1520
Error
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import * as Sentry from '@sentry/solidjs';
2+
import { ErrorBoundary } from 'solid-js';
3+
4+
const SentryErrorBoundary = Sentry.withSentryErrorBoundary(ErrorBoundary);
5+
6+
export default function ErrorBoundaryExample() {
7+
return (
8+
<SentryErrorBoundary
9+
fallback={(error, reset) => (
10+
<section class="bg-gray-100 text-gray-700 p-8">
11+
<h1 class="text-2xl font-bold">Error Boundary Fallback</h1>
12+
<div class="flex items-center space-x-2 mb-4">
13+
<code>{error.message}</code>
14+
</div>
15+
<button id="errorBoundaryResetBtn" class="border rounded-lg px-2 border-gray-900" onClick={reset}>
16+
Reset
17+
</button>
18+
</section>
19+
)}
20+
>
21+
<NonExistentComponent />
22+
</SentryErrorBoundary>
23+
);
24+
}

dev-packages/e2e-tests/test-applications/solidjs/src/routes.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { lazy } from 'solid-js';
22

3+
import ErrorBoundaryExample from './pages/errorboundaryexample';
34
import Home from './pages/home';
45

56
export const routes = [
@@ -11,6 +12,10 @@ export const routes = [
1112
path: '/user/:id',
1213
component: lazy(() => import('./pages/user')),
1314
},
15+
{
16+
path: '/error-boundary-example',
17+
component: ErrorBoundaryExample,
18+
},
1419
{
1520
path: '**',
1621
component: lazy(() => import('./errors/404')),
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { expect, test } from '@playwright/test';
2+
import { waitForError } from '@sentry-internal/test-utils';
3+
4+
test('captures an exception', async ({ page }) => {
5+
const errorEventPromise = waitForError('solidjs', errorEvent => {
6+
return !errorEvent.type;
7+
});
8+
9+
const [, errorEvent] = await Promise.all([page.goto('/error-boundary-example'), errorEventPromise]);
10+
11+
expect(errorEvent).toMatchObject({
12+
exception: {
13+
values: [
14+
{
15+
type: 'ReferenceError',
16+
value: 'NonExistentComponent is not defined',
17+
mechanism: {
18+
type: 'generic',
19+
handled: true,
20+
},
21+
},
22+
],
23+
},
24+
transaction: '/error-boundary-example',
25+
});
26+
});
27+
28+
test('captures a second exception after resetting the boundary', async ({ page }) => {
29+
const firstErrorEventPromise = waitForError('solidjs', errorEvent => {
30+
return !errorEvent.type;
31+
});
32+
33+
const [, firstErrorEvent] = await Promise.all([page.goto('/error-boundary-example'), firstErrorEventPromise]);
34+
35+
expect(firstErrorEvent).toMatchObject({
36+
exception: {
37+
values: [
38+
{
39+
type: 'ReferenceError',
40+
value: 'NonExistentComponent is not defined',
41+
mechanism: {
42+
type: 'generic',
43+
handled: true,
44+
},
45+
},
46+
],
47+
},
48+
transaction: '/error-boundary-example',
49+
});
50+
51+
const secondErrorEventPromise = waitForError('solidjs', errorEvent => {
52+
return !errorEvent.type;
53+
});
54+
55+
const [, secondErrorEvent] = await Promise.all([
56+
page.locator('#errorBoundaryResetBtn').click(),
57+
await secondErrorEventPromise,
58+
]);
59+
60+
expect(secondErrorEvent).toMatchObject({
61+
exception: {
62+
values: [
63+
{
64+
type: 'ReferenceError',
65+
value: 'NonExistentComponent is not defined',
66+
mechanism: {
67+
type: 'generic',
68+
handled: true,
69+
},
70+
},
71+
],
72+
},
73+
transaction: '/error-boundary-example',
74+
});
75+
});

0 commit comments

Comments
 (0)