Skip to content

Commit c0683ee

Browse files
committed
feat(svelte-integration): add global error handlers test pages in svelte playground
1 parent 8f7960d commit c0683ee

File tree

6 files changed

+293
-0
lines changed

6 files changed

+293
-0
lines changed

packages/svelte/playground/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ Test playground for Hawk Error Tracker integration with SvelteKit and Svelte.
55
## Table of Contents
66

77
- [Getting Started](#getting-started)
8+
- [Error Handling](#error-handling)
9+
- [Error Test Pages](#error-test-pages)
810

911
## Getting Started
1012

@@ -21,3 +23,28 @@ yarn install
2123
```shell
2224
yarn dev
2325
```
26+
27+
## Error Handling
28+
29+
### Global Error Handlers (🔴)
30+
31+
Global browser error handlers that catch unhandled errors:
32+
33+
- **`window.error`**
34+
- **`window.unhandledrejection`**
35+
36+
**Note:** global errors will be caught using Hawk Catcher.
37+
38+
## Error Test Pages
39+
40+
The playground includes test pages to demonstrate each error catching mechanism:
41+
42+
### Global Error Handlers (🔴)
43+
44+
1. **Runtime Error** (`/errors/runtime-error`)
45+
- Demonstrates synchronous error in event handler
46+
- Caught by `window.error`
47+
48+
2. **Promise Rejection** (`/errors/promise-rejection`)
49+
- Demonstrates unhandled Promise rejection
50+
- Caught by `window.unhandledrejection`
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
2+
3+
:root {
4+
--bg-primary: #2f3341;
5+
--bg-secondary: #242732;
6+
--text-primary: #dbe6ff;
7+
--text-secondary: rgba(219, 230, 255, 0.6);
8+
--border-color: rgba(219, 230, 255, 0.1);
9+
--button-primary: #4979e4;
10+
--button-primary-hover: #4869d2;
11+
}
12+
13+
body {
14+
font-family: Roboto, system-ui, sans-serif;
15+
margin: 0;
16+
padding: 0;
17+
background: var(--bg-primary);
18+
color: var(--text-primary);
19+
font-size: 13px;
20+
}
21+
22+
header {
23+
padding: 30px;
24+
background: var(--bg-secondary);
25+
}
26+
27+
h1 {
28+
font-weight: bold;
29+
font-size: 20px;
30+
margin: 0 0 15px;
31+
color: var(--text-primary);
32+
}
33+
34+
h2 {
35+
font-weight: 500;
36+
margin: 0 0 10px;
37+
font-size: 13px;
38+
color: var(--text-secondary);
39+
letter-spacing: 0.24px;
40+
text-transform: uppercase;
41+
}
42+
43+
h3 {
44+
margin: 0 0 10px 0;
45+
color: var(--text-primary);
46+
font-size: 16px;
47+
font-weight: 500;
48+
}
49+
50+
p {
51+
margin: 0.5rem 0;
52+
color: var(--text-primary);
53+
}
54+
55+
a {
56+
color: inherit;
57+
text-decoration: underline;
58+
}
59+
60+
a:hover {
61+
color: var(--button-primary);
62+
}
63+
64+
section {
65+
padding: 15px;
66+
border: 1px solid var(--border-color);
67+
border-radius: 4px;
68+
margin: 15px;
69+
}
70+
71+
button {
72+
display: inline-block;
73+
padding: 8px 20px;
74+
border: 0;
75+
border-radius: 5px;
76+
background: var(--button-primary);
77+
color: var(--text-primary);
78+
font-weight: 500;
79+
font-size: 14px;
80+
cursor: pointer;
81+
font-family: inherit;
82+
}
83+
84+
button:hover {
85+
background: var(--button-primary-hover);
86+
}
87+
88+
button:disabled {
89+
opacity: 0.5;
90+
cursor: not-allowed;
91+
}
92+
93+
code {
94+
background: var(--bg-secondary);
95+
padding: 2px 6px;
96+
border-radius: 3px;
97+
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
98+
font-size: 0.9em;
99+
}
100+
101+
.container {
102+
max-width: 1200px;
103+
margin: 0 auto;
104+
padding: 20px;
105+
}
106+
107+
.grid {
108+
display: grid;
109+
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
110+
gap: 15px;
111+
}
112+
113+
.test-card {
114+
display: block;
115+
padding: 20px;
116+
border: 2px solid var(--border-color);
117+
border-radius: 8px;
118+
text-decoration: none;
119+
color: inherit;
120+
transition: all 0.2s ease;
121+
background: var(--bg-secondary);
122+
}
123+
124+
.test-card:hover {
125+
border-color: var(--button-primary);
126+
transform: translateY(-2px);
127+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
128+
}
129+
130+
.test-card h3 {
131+
margin: 0 0 10px 0;
132+
font-size: 16px;
133+
}
134+
135+
.test-card p {
136+
margin: 0;
137+
color: var(--text-secondary);
138+
font-size: 13px;
139+
line-height: 1.5;
140+
}
141+
142+
.alert {
143+
padding: 15px;
144+
border-left: 4px solid;
145+
border-radius: 4px;
146+
margin: 15px 0;
147+
}
148+
149+
.alert-warning {
150+
background: rgba(255, 193, 7, 0.15);
151+
border-color: #ffc107;
152+
color: #ffd54f;
153+
}
154+
155+
.error-fallback {
156+
padding: 1.5rem;
157+
background: rgba(244, 67, 54, 0.15);
158+
border-left: 4px solid #f44336;
159+
border-radius: 4px;
160+
}
161+
162+
.error-fallback h3 {
163+
margin: 0 0 0.5rem 0;
164+
color: #ff8a80;
165+
}
166+
167+
.error-fallback p {
168+
margin: 0.5rem 0;
169+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
window.addEventListener('error', (event) => {
2+
console.error('🔴 [window.error]', event.error, `at ${event.filename}:${event.lineno}`);
3+
});
4+
5+
window.addEventListener('unhandledrejection', (event) => {
6+
console.error('🔴 [window.unhandledrejection]', event.reason);
7+
});
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,63 @@
1+
<script lang="ts">
2+
interface ErrorTest {
3+
title: string;
4+
description: string;
5+
href: string;
6+
category: string;
7+
}
8+
9+
const errorTests: ErrorTest[] = [
10+
// Window Error Handlers
11+
{
12+
title: 'Synchronous Runtime Error',
13+
description: 'Error thrown in event handler',
14+
href: '/errors/runtime-error',
15+
category: 'Global Error Handlers (🔴)'
16+
},
17+
{
18+
title: 'Unhandled Promise Rejection',
19+
description: 'Promise rejected without catch handler',
20+
href: '/errors/promise-rejection',
21+
category: 'Global Error Handlers (🔴)'
22+
},
23+
];
24+
25+
const categories = Array.from(new Set(errorTests.map(t => t.category)));
26+
</script>
27+
128
<svelte:head>
229
<title>Hawk Javascript SvelteKit Integration Playground</title>
330
</svelte:head>
31+
32+
<div class="container">
33+
<header>
34+
<h1>🧪 SvelteKit Error Handling Test Suite</h1>
35+
</header>
36+
37+
<div class="alert alert-warning">
38+
<strong>⚠️ Testing Instructions:</strong>
39+
<ul>
40+
<li>Open your browser's DevTools Console to see error logs</li>
41+
<li>Look for colored emoji markers:
42+
<ul>
43+
<li>🔴 = Caught by global <code>window.error</code> or <code>window.unhandledrejection</code></li>
44+
</ul>
45+
</li>
46+
<li>Each test demonstrates where errors are caught in the SvelteKit error handling hierarchy</li>
47+
</ul>
48+
</div>
49+
50+
{#each categories as category}
51+
<section>
52+
<h2>{category}</h2>
53+
<div class="grid">
54+
{#each errorTests.filter(t => t.category === category) as test}
55+
<a href={test.href} class="test-card" data-sveltekit-preload-data="off">
56+
<h3>{test.title}</h3>
57+
<p>{test.description}</p>
58+
</a>
59+
{/each}
60+
</div>
61+
</section>
62+
{/each}
63+
</div>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script lang="ts">
2+
function triggerRejection() {
3+
Promise.reject(new Error('Unhandled promise rejection'));
4+
}
5+
</script>
6+
7+
<div class="container">
8+
<h1>Unhandled Promise Rejection Test</h1>
9+
<p>Click the button to trigger an unhandled promise rejection.</p>
10+
<p><strong>Caught by:</strong> <code>window.unhandledrejection</code> (🔴 red dot in console)</p>
11+
12+
<button onclick={triggerRejection}>
13+
Trigger Promise Rejection
14+
</button>
15+
</div>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script lang="ts">
2+
function triggerError() {
3+
throw new Error('Runtime error caught by window.onerror');
4+
}
5+
</script>
6+
7+
<div class="container">
8+
<h1>Window Error Handler Test</h1>
9+
<p>Click the button to trigger a runtime error.</p>
10+
<p><strong>Caught by:</strong> <code>window.onerror</code> (🔴 red dot in console)</p>
11+
12+
<button onclick={triggerError}>
13+
Trigger Runtime Error
14+
</button>
15+
</div>

0 commit comments

Comments
 (0)