Skip to content

Commit d36bc12

Browse files
init: remove tracking (#2992)
1 parent 373ea7d commit d36bc12

9 files changed

+303
-1162
lines changed

app/global-error.tsx

Lines changed: 216 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,140 @@
1-
'use client';
2-
import { useEffect, useRef, useState, useMemo } from 'react';
3-
import * as Sentry from '@sentry/nextjs';
1+
'use client'
2+
import { useRef, useState, useMemo } from 'react'
43
import { detectBotFromUserAgent } from '@/utils/logEvent'
5-
import DOMPurify from 'dompurify';
4+
import DOMPurify from 'dompurify'
65

76
function snapshotSanitizedSSR(): string | null {
87
try {
9-
if (typeof document === 'undefined') return null;
8+
if (typeof document === 'undefined') return null
109

1110
// Clone current body and strip dangerous elements
12-
const bodyClone = document.body.cloneNode(true) as HTMLElement;
13-
bodyClone.querySelectorAll('script, object, embed, iframe').forEach((n) => n.remove());
14-
bodyClone.querySelectorAll('link[rel="modulepreload"], link[as="script"]').forEach((n) => n.remove());
15-
16-
const html = bodyClone.innerHTML || '';
17-
18-
if (html.trim().length === 0) return null;
19-
11+
const bodyClone = document.body.cloneNode(true) as HTMLElement
12+
bodyClone.querySelectorAll('script, object, embed, iframe').forEach((n) => n.remove())
13+
bodyClone
14+
.querySelectorAll('link[rel="modulepreload"], link[as="script"]')
15+
.forEach((n) => n.remove())
16+
17+
const html = bodyClone.innerHTML || ''
18+
19+
if (html.trim().length === 0) return null
20+
2021
// Sanitize with DOMPurify for enhanced security
2122
const sanitized = DOMPurify.sanitize(html, {
2223
ALLOWED_TAGS: [
23-
'div', 'span', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
24-
'a', 'img', 'ul', 'ol', 'li', 'br', 'strong', 'em', 'b', 'i',
25-
'article', 'section', 'nav', 'header', 'footer', 'main', 'aside',
26-
'table', 'thead', 'tbody', 'tr', 'td', 'th', 'code', 'pre',
27-
'blockquote', 'figure', 'figcaption', 'time', 'small'
24+
'div',
25+
'span',
26+
'p',
27+
'h1',
28+
'h2',
29+
'h3',
30+
'h4',
31+
'h5',
32+
'h6',
33+
'a',
34+
'img',
35+
'ul',
36+
'ol',
37+
'li',
38+
'br',
39+
'strong',
40+
'em',
41+
'b',
42+
'i',
43+
'article',
44+
'section',
45+
'nav',
46+
'header',
47+
'footer',
48+
'main',
49+
'aside',
50+
'table',
51+
'thead',
52+
'tbody',
53+
'tr',
54+
'td',
55+
'th',
56+
'code',
57+
'pre',
58+
'blockquote',
59+
'figure',
60+
'figcaption',
61+
'time',
62+
'small',
2863
],
2964
ALLOWED_ATTR: [
30-
'class', 'id', 'href', 'src', 'alt', 'title', 'role',
31-
'aria-label', 'aria-labelledby', 'aria-describedby',
32-
'data-testid', 'data-id', 'width', 'height'
65+
'class',
66+
'id',
67+
'href',
68+
'src',
69+
'alt',
70+
'title',
71+
'role',
72+
'aria-label',
73+
'aria-labelledby',
74+
'aria-describedby',
75+
'data-testid',
76+
'data-id',
77+
'width',
78+
'height',
3379
],
34-
FORBID_TAGS: ['script', 'object', 'embed', 'iframe', 'form', 'input', 'button', 'select', 'textarea'],
35-
FORBID_ATTR: ['onload', 'onclick', 'onerror', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'style'],
36-
KEEP_CONTENT: true // Keep text content even if wrapper is removed
37-
});
38-
39-
return sanitized.trim().length > 0 ? sanitized : null;
80+
FORBID_TAGS: [
81+
'script',
82+
'object',
83+
'embed',
84+
'iframe',
85+
'form',
86+
'input',
87+
'button',
88+
'select',
89+
'textarea',
90+
],
91+
FORBID_ATTR: [
92+
'onload',
93+
'onclick',
94+
'onerror',
95+
'onmouseover',
96+
'onmouseout',
97+
'onfocus',
98+
'onblur',
99+
'style',
100+
],
101+
KEEP_CONTENT: true, // Keep text content even if wrapper is removed
102+
})
103+
104+
return sanitized.trim().length > 0 ? sanitized : null
40105
} catch {
41-
return null;
106+
return null
42107
}
43108
}
44109

45-
export default function GlobalError({ error, reset }: { error: Error & { digest?: string }, reset: () => void }) {
46-
const preservedRef = useRef<string | null>(null);
110+
export default function GlobalError({
111+
reset,
112+
}: {
113+
error: Error & { digest?: string }
114+
reset: () => void
115+
}) {
116+
const preservedRef = useRef<string | null>(null)
47117
if (preservedRef.current === null) {
48118
// Attempt to grab SSR HTML immediately
49-
preservedRef.current = snapshotSanitizedSSR();
119+
preservedRef.current = snapshotSanitizedSSR()
50120
}
51121

52-
const [showOverlay, setShowOverlay] = useState(true);
122+
const [showOverlay, setShowOverlay] = useState(true)
53123

54124
// Overlay is not shown for bot requests, using the same bot detection as in middleware.ts
55125
const isBotUA = (() => {
56126
if (typeof navigator === 'undefined') return false
57127
const { isBot } = detectBotFromUserAgent(navigator.userAgent || '')
58128
return isBot
59-
})();
129+
})()
60130

61-
useEffect(() => {
62-
try {
63-
Sentry.withScope((scope) => {
64-
scope.setTag('errorBoundary', 'global')
65-
scope.setTag('severity', 'critical')
66-
scope.setLevel('fatal')
67-
if (typeof window !== 'undefined') {
68-
scope.setContext('browser', {
69-
url: window.location.href,
70-
userAgent: window.navigator.userAgent,
71-
preservedSSR: preservedRef.current,
72-
})
73-
}
74-
scope.setContext('error', {
75-
name: error.name,
76-
message: error.message,
77-
fullError: error,
78-
})
79-
Sentry.captureException(error)
80-
})
81-
} catch (_) { /* cannot do much if Sentry fails */ }
82-
}, [error])
83-
84-
const hasPreserved = Boolean(preservedRef.current && preservedRef.current.length > 200);
131+
const hasPreserved = Boolean(preservedRef.current && preservedRef.current.length > 200)
85132

86133
// Memoize the sanitized HTML to avoid re-processing
87134
const sanitizedHTML = useMemo(() => {
88-
if (!preservedRef.current) return '';
89-
return preservedRef.current; // Already sanitized in snapshotSanitizedSSR
90-
}, []);
135+
if (!preservedRef.current) return ''
136+
return preservedRef.current // Already sanitized in snapshotSanitizedSSR
137+
}, [])
91138

92139
return (
93140
<html lang="en">
@@ -109,54 +156,139 @@ export default function GlobalError({ error, reset }: { error: Error & { digest?
109156
content="SigNoz is an open-source observability tool powered by OpenTelemetry. Get APM, logs, traces, metrics, exceptions, & alerts in a single tool."
110157
/>
111158
</head>
112-
<body style={{
113-
background: '#111113', color: '#f3f4f6', margin: 0, padding: 0, fontFamily: 'system-ui,sans-serif', minHeight: '100vh', maxHeight: 'fit-content'
114-
}}>
159+
<body
160+
style={{
161+
background: '#111113',
162+
color: '#f3f4f6',
163+
margin: 0,
164+
padding: 0,
165+
fontFamily: 'system-ui,sans-serif',
166+
minHeight: '100vh',
167+
maxHeight: 'fit-content',
168+
}}
169+
>
115170
{hasPreserved && showOverlay && !isBotUA && (
116-
<div style={{
117-
position: 'fixed', bottom: 0, left: 0, right: 0, zIndex: 100000,
118-
backgroundColor: 'rgba(249, 115, 22, 0.95)', color: '#fff', padding: '10px 16px',
119-
display: 'flex', alignItems: 'center', justifyContent: 'space-between',
120-
borderTop: '2px solid #ea580c', boxShadow: '0 -8px 24px rgba(0,0,0,0.25)'
121-
}}>
171+
<div
172+
style={{
173+
position: 'fixed',
174+
bottom: 0,
175+
left: 0,
176+
right: 0,
177+
zIndex: 100000,
178+
backgroundColor: 'rgba(249, 115, 22, 0.95)',
179+
color: '#fff',
180+
padding: '10px 16px',
181+
display: 'flex',
182+
alignItems: 'center',
183+
justifyContent: 'space-between',
184+
borderTop: '2px solid #ea580c',
185+
boxShadow: '0 -8px 24px rgba(0,0,0,0.25)',
186+
}}
187+
>
122188
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
123-
<div style={{ width: 22, height: 22, background: '#fff', color: '#f97316', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 13, fontWeight: 700 }}>!</div>
124-
<div><strong>Resource loading issue.</strong> The page below is server-rendered and still readable.</div>
189+
<div
190+
style={{
191+
width: 22,
192+
height: 22,
193+
background: '#fff',
194+
color: '#f97316',
195+
borderRadius: '50%',
196+
display: 'flex',
197+
alignItems: 'center',
198+
justifyContent: 'center',
199+
fontSize: 13,
200+
fontWeight: 700,
201+
}}
202+
>
203+
!
204+
</div>
205+
<div>
206+
<strong>Resource loading issue.</strong> The page below is server-rendered and still
207+
readable.
208+
</div>
125209
</div>
126210
<div style={{ display: 'flex', gap: 8 }}>
127-
<button onClick={() => (typeof window !== 'undefined' ? window.location.reload() : reset())} style={{ background: '#fff', color: '#f97316', border: 'none', borderRadius: 6, padding: '6px 10px', fontSize: 12, fontWeight: 600, cursor: 'pointer' }}>Reload</button>
128-
<button onClick={() => setShowOverlay(false)} style={{ background: 'transparent', color: '#fff', border: '1px solid #fff', borderRadius: 6, padding: '6px 10px', fontSize: 12, fontWeight: 600, cursor: 'pointer' }}>Dismiss</button>
211+
<button
212+
onClick={() => (typeof window !== 'undefined' ? window.location.reload() : reset())}
213+
style={{
214+
background: '#fff',
215+
color: '#f97316',
216+
border: 'none',
217+
borderRadius: 6,
218+
padding: '6px 10px',
219+
fontSize: 12,
220+
fontWeight: 600,
221+
cursor: 'pointer',
222+
}}
223+
>
224+
Reload
225+
</button>
226+
<button
227+
onClick={() => setShowOverlay(false)}
228+
style={{
229+
background: 'transparent',
230+
color: '#fff',
231+
border: '1px solid #fff',
232+
borderRadius: 6,
233+
padding: '6px 10px',
234+
fontSize: 12,
235+
fontWeight: 600,
236+
cursor: 'pointer',
237+
}}
238+
>
239+
Dismiss
240+
</button>
129241
</div>
130242
</div>
131243
)}
132244

133245
{hasPreserved ? (
134246
<div dangerouslySetInnerHTML={{ __html: sanitizedHTML }} />
135247
) : (
136-
<div style={{
137-
margin: 'auto', maxWidth: 560, padding: 32, background: '#1e1f24',
138-
borderRadius: 16, border: '1px solid #30323a', boxShadow: '0 24px 48px #000a'
139-
}}>
248+
<div
249+
style={{
250+
margin: 'auto',
251+
maxWidth: 560,
252+
padding: 32,
253+
background: '#1e1f24',
254+
borderRadius: 16,
255+
border: '1px solid #30323a',
256+
boxShadow: '0 24px 48px #000a',
257+
}}
258+
>
140259
<div style={{ fontSize: 48, marginBottom: 18 }}>🚨</div>
141260
<h1 style={{ fontSize: 28, marginBottom: 12 }}>Critical Application Error</h1>
142261
<p style={{ color: '#9ca3af', marginBottom: 12 }}>
143-
The application failed to initialize due to a critical error. Server-rendered content may be unavailable.
262+
The application failed to initialize due to a critical error. Server-rendered content
263+
may be unavailable.
144264
</p>
145265
<div style={{ display: 'flex', gap: 10, justifyContent: 'center', marginTop: 16 }}>
146266
<button
147267
onClick={() => (typeof window !== 'undefined' ? window.location.reload() : reset())}
148268
style={{
149-
background: '#3b82f6', color: '#fff', border: 'none', borderRadius: 8,
150-
padding: '10px 16px', fontWeight: 600, cursor: 'pointer'
269+
background: '#3b82f6',
270+
color: '#fff',
271+
border: 'none',
272+
borderRadius: 8,
273+
padding: '10px 16px',
274+
fontWeight: 600,
275+
cursor: 'pointer',
151276
}}
152277
>
153278
Reload
154279
</button>
155280
<button
156-
onClick={() => (typeof window !== 'undefined' ? (window.location.href = '/') : reset())}
281+
onClick={() =>
282+
typeof window !== 'undefined' ? (window.location.href = '/') : reset()
283+
}
157284
style={{
158-
background: 'transparent', color: '#9ca3af', border: '1px solid #4b5563', borderRadius: 8,
159-
padding: '10px 16px', fontWeight: 600, cursor: 'pointer'
285+
background: 'transparent',
286+
color: '#9ca3af',
287+
border: '1px solid #4b5563',
288+
borderRadius: 8,
289+
padding: '10px 16px',
290+
fontWeight: 600,
291+
cursor: 'pointer',
160292
}}
161293
>
162294
Go Home
@@ -166,5 +298,5 @@ export default function GlobalError({ error, reset }: { error: Error & { digest?
166298
)}
167299
</body>
168300
</html>
169-
);
301+
)
170302
}

error-tracking.client.config.ts

Lines changed: 0 additions & 14 deletions
This file was deleted.

error-tracking.edge.config.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)