Skip to content

Commit 333c637

Browse files
committed
feat: Add Sentry error tracking across all services
- Add Sentry integration to backend services (Agent, Chat, Knowledge Base) - Add Sentry to Next.js frontend with error boundaries - Add Sentry to widget for browser error tracking - Add Sentry to Python voice agent service - Simplify Sentry config to production-only mode - Improve widget error handling and logging - Update widget test page with correct API key format - Add comprehensive Sentry documentation
1 parent 88246b5 commit 333c637

33 files changed

Lines changed: 834 additions & 369 deletions

WIDGET_DEPLOYMENT.md

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

frontend/app/error.tsx

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* Global Error Boundary
3+
* Catches errors in the app directory
4+
*/
5+
6+
'use client'
7+
8+
import * as Sentry from '@sentry/nextjs'
9+
import { useEffect } from 'react'
10+
import { Button } from '@/components/ui/button'
11+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
12+
import { AlertCircle } from 'lucide-react'
13+
14+
export default function Error({
15+
error,
16+
reset,
17+
}: {
18+
error: Error & { digest?: string }
19+
reset: () => void
20+
}) {
21+
useEffect(() => {
22+
// Log error to Sentry
23+
Sentry.captureException(error)
24+
}, [error])
25+
26+
return (
27+
<div className="flex min-h-screen items-center justify-center p-4">
28+
<Card className="w-full max-w-md">
29+
<CardHeader>
30+
<div className="flex items-center gap-2">
31+
<AlertCircle className="h-5 w-5 text-destructive" />
32+
<CardTitle>Something went wrong</CardTitle>
33+
</div>
34+
<CardDescription>
35+
An unexpected error occurred. We've been notified and are working on a fix.
36+
</CardDescription>
37+
</CardHeader>
38+
<CardContent className="space-y-4">
39+
{process.env.NODE_ENV === 'development' && (
40+
<div className="rounded-md bg-muted p-4">
41+
<p className="text-sm font-mono text-muted-foreground">
42+
{error.message}
43+
</p>
44+
</div>
45+
)}
46+
<div className="flex gap-2">
47+
<Button onClick={reset} variant="default">
48+
Try again
49+
</Button>
50+
<Button onClick={() => window.location.href = '/'} variant="outline">
51+
Go home
52+
</Button>
53+
</div>
54+
</CardContent>
55+
</Card>
56+
</div>
57+
)
58+
}
59+

frontend/app/global-error.tsx

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* Global Error Boundary for Root Layout
3+
* Catches errors that occur in the root layout
4+
*/
5+
6+
'use client'
7+
8+
import * as Sentry from '@sentry/nextjs'
9+
import { useEffect } from 'react'
10+
11+
export default function GlobalError({
12+
error,
13+
reset,
14+
}: {
15+
error: Error & { digest?: string }
16+
reset: () => void
17+
}) {
18+
useEffect(() => {
19+
// Log error to Sentry
20+
Sentry.captureException(error)
21+
}, [error])
22+
23+
return (
24+
<html>
25+
<body>
26+
<div style={{
27+
display: 'flex',
28+
flexDirection: 'column',
29+
alignItems: 'center',
30+
justifyContent: 'center',
31+
minHeight: '100vh',
32+
padding: '2rem',
33+
fontFamily: 'system-ui, sans-serif',
34+
}}>
35+
<h1 style={{ fontSize: '1.5rem', marginBottom: '1rem' }}>
36+
Something went wrong
37+
</h1>
38+
<p style={{ marginBottom: '2rem', color: '#666' }}>
39+
An unexpected error occurred. Please try refreshing the page.
40+
</p>
41+
<button
42+
onClick={reset}
43+
style={{
44+
padding: '0.5rem 1rem',
45+
backgroundColor: '#000',
46+
color: '#fff',
47+
border: 'none',
48+
borderRadius: '0.25rem',
49+
cursor: 'pointer',
50+
}}
51+
>
52+
Try again
53+
</button>
54+
</div>
55+
</body>
56+
</html>
57+
)
58+
}
59+

frontend/components/voice-call/voice-call-widget.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export function VoiceCallWidget({ conversationId, agentId }: VoiceCallWidgetProp
113113
data: {
114114
status: 'ended',
115115
metadata: {
116-
ended_at: new Date().toISOString(),
116+
ended_at: new Date().toISOString(),
117117
},
118118
},
119119
})

frontend/instrumentation.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Next.js Instrumentation Hook
3+
* This file is executed once when the server starts
4+
*/
5+
6+
export async function register() {
7+
if (process.env.NEXT_RUNTIME === 'nodejs') {
8+
// Only initialize Sentry on server-side
9+
if (process.env.SENTRY_DSN) {
10+
await import('./sentry.server.config')
11+
}
12+
}
13+
14+
if (process.env.NEXT_RUNTIME === 'edge') {
15+
// Initialize Sentry for edge runtime
16+
if (process.env.SENTRY_DSN) {
17+
await import('./sentry.edge.config')
18+
}
19+
}
20+
}
21+

frontend/next.config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ const nextConfig: NextConfig = {
4141
// Ensure CSS is properly compiled with Tailwind v4
4242
experimental: {
4343
optimizeCss: true,
44+
// Enable instrumentation hook for Sentry
45+
instrumentationHook: true,
4446
},
4547
// Transpile shared package for Next.js
4648
transpilePackages: ['@syntera/shared'],

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"@radix-ui/react-switch": "^1.2.6",
3636
"@radix-ui/react-tabs": "^1.1.13",
3737
"@radix-ui/react-tooltip": "^1.2.8",
38+
"@sentry/nextjs": "^8.45.0",
3839
"@supabase/ssr": "^0.7.0",
3940
"@supabase/supabase-js": "^2.81.1",
4041
"@syntera/shared": "workspace:*",

0 commit comments

Comments
 (0)