Documentation Index Fetch the complete documentation index at: https://mintlify.com/kuestcom/prediction-market/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Kuest integrates with Sentry for comprehensive error tracking, performance monitoring, and debugging. This guide covers monitoring setup, health checks, and troubleshooting.
Sentry Integration
Configuration
Sentry is configured in multiple files for complete coverage:
// sentry.server.config.ts
import * as Sentry from '@sentry/nextjs'
Sentry . init ({
dsn: process . env . SENTRY_DSN ,
tracesSampleRate: 0.1 , // 10% of transactions
enableLogs: true , // Capture console logs
})
// src/instrumentation.ts
import * as Sentry from '@sentry/nextjs'
export async function register () {
await import ( '../sentry.server.config' )
}
export const onRequestError = Sentry . captureRequestError
Environment Variables
Configure Sentry in your .env file:
# Required
SENTRY_DSN = "https://[key]@[org].ingest.sentry.io/[project]"
# Optional (for source maps and releases)
SENTRY_ORG = "your-org-slug"
SENTRY_PROJECT = "your-project-slug"
SENTRY_AUTH_TOKEN = "your-auth-token"
Create Sentry Project
Sign up at sentry.io
Create a new project (choose Next.js)
Copy your DSN from project settings
Configure Environment
Add your SENTRY_DSN to .env: SENTRY_DSN = "https://abc123@o123456.ingest.sentry.io/7890123"
Deploy with Source Maps
Configure authentication for source map uploads: SENTRY_AUTH_TOKEN = "your-token-from-settings"
Source maps help debug minified production code by showing original source locations.
Error Tracking
Automatic Error Capture
Sentry automatically captures:
Unhandled Exceptions Runtime errors that crash the application
Promise Rejections Unhandled rejected promises
Server Errors API route failures and server-side errors
Client Errors Browser-side JavaScript errors
Manual Error Reporting
Capture errors explicitly when needed:
import * as Sentry from '@sentry/nextjs'
try {
await riskyOperation ()
} catch ( error ) {
// Log to console
console . error ( 'Operation failed:' , error )
// Send to Sentry with context
Sentry . captureException ( error , {
tags: {
operation: 'riskyOperation' ,
severity: 'high'
},
extra: {
userId: user . id ,
marketId: market . id ,
timestamp: Date . now ()
}
})
// Handle gracefully
return { success: false , error: 'Operation failed' }
}
Error Context
Enrich errors with additional context:
// Set user context
Sentry . setUser ({
id: user . id ,
email: user . email ,
username: user . username ,
wallet: user . address ,
})
// Add breadcrumbs
Sentry . addBreadcrumb ({
category: 'trading' ,
message: 'User initiated trade' ,
level: 'info' ,
data: {
marketId: trade . marketId ,
amount: trade . amount ,
outcome: trade . outcome ,
}
})
// Set tags for filtering
Sentry . setTag ( 'market_type' , 'binary' )
Sentry . setTag ( 'network' , 'polygon' )
Sentry . setTag ( 'feature' , 'trading' )
Health Checks
API Health Endpoint
While not explicitly implemented in the source, you should add a health check endpoint:
// src/app/api/health/route.ts
import { NextResponse } from 'next/server'
import { db } from '@/lib/drizzle'
export const dynamic = 'force-dynamic'
export const runtime = 'edge'
export async function GET () {
const startTime = Date . now ()
try {
// Check database connection
await db . execute ( 'SELECT 1' )
const responseTime = Date . now () - startTime
return NextResponse . json ({
status: 'healthy' ,
timestamp: new Date (). toISOString (),
responseTime: ` ${ responseTime } ms` ,
services: {
database: 'connected' ,
storage: process . env . S3_BUCKET ? 'configured' : 'not configured' ,
sentry: process . env . SENTRY_DSN ? 'enabled' : 'disabled' ,
}
})
} catch ( error ) {
return NextResponse . json (
{
status: 'unhealthy' ,
error: error instanceof Error ? error . message : 'Unknown error' ,
timestamp: new Date (). toISOString (),
},
{ status: 503 }
)
}
}
Cron Job Monitoring
Monitor automated tasks:
// Example: Resolution sync monitoring
export async function GET ( request : Request ) {
const auth = request . headers . get ( 'authorization' )
if ( ! isCronAuthorized ( auth , process . env . CRON_SECRET )) {
Sentry . captureMessage ( 'Unauthorized cron attempt' , {
level: 'warning' ,
tags: { cron: 'resolution_sync' }
})
return NextResponse . json ({ error: 'Unauthenticated.' }, { status: 401 })
}
try {
const syncResult = await syncResolutions ()
// Log success metrics
Sentry . captureMessage ( 'Resolution sync completed' , {
level: 'info' ,
tags: { cron: 'resolution_sync' },
extra: {
fetched: syncResult . fetchedCount ,
processed: syncResult . processedCount ,
skipped: syncResult . skippedCount ,
errors: syncResult . errors . length ,
timeLimitReached: syncResult . timeLimitReached ,
}
})
return NextResponse . json ({
success: true ,
... syncResult
})
} catch ( error : any ) {
// Capture cron failure
Sentry . captureException ( error , {
tags: { cron: 'resolution_sync' },
level: 'error'
})
return NextResponse . json (
{ success: false , error: error . message },
{ status: 500 }
)
}
}
Database Health
Monitor database performance:
// Track slow queries
import { db } from '@/lib/drizzle'
async function trackQuery < T >(
queryName : string ,
queryFn : () => Promise < T >
) : Promise < T > {
const startTime = performance . now ()
try {
const result = await queryFn ()
const duration = performance . now () - startTime
// Log slow queries
if ( duration > 1000 ) {
Sentry . captureMessage ( `Slow query: ${ queryName } ` , {
level: 'warning' ,
tags: { query: queryName },
extra: { duration: ` ${ duration } ms` }
})
}
return result
} catch ( error ) {
Sentry . captureException ( error , {
tags: { query: queryName },
extra: { duration: ` ${ performance . now () - startTime } ms` }
})
throw error
}
}
// Usage
const events = await trackQuery (
'getActiveEvents' ,
() => EventRepository . getActiveEvents ()
)
Transaction Tracking
Track performance of key operations:
import * as Sentry from '@sentry/nextjs'
// Start a transaction
const transaction = Sentry . startTransaction ({
name: 'Market Creation' ,
op: 'market.create'
})
try {
// Track sub-operations
const slugCheckSpan = transaction . startChild ({
op: 'validation' ,
description: 'Check slug uniqueness'
})
await checkSlugUniqueness ( slug )
slugCheckSpan . finish ()
const aiValidationSpan = transaction . startChild ({
op: 'ai' ,
description: 'AI content validation'
})
await validateContentWithAI ( content )
aiValidationSpan . finish ()
const blockchainSpan = transaction . startChild ({
op: 'blockchain' ,
description: 'Deploy to blockchain'
})
await deployMarket ( marketData )
blockchainSpan . finish ()
transaction . setStatus ( 'ok' )
} catch ( error ) {
transaction . setStatus ( 'internal_error' )
Sentry . captureException ( error )
} finally {
transaction . finish ()
}
Custom Metrics
Track business metrics:
// Track user actions
Sentry . addBreadcrumb ({
category: 'user.action' ,
message: 'User placed trade' ,
level: 'info' ,
data: {
tradeValue: trade . amount ,
market: trade . marketId ,
outcome: trade . outcome
}
})
// Track API performance
Sentry . addBreadcrumb ({
category: 'api.call' ,
message: 'Kuest API order placement' ,
level: 'info' ,
data: {
endpoint: '/orders' ,
responseTime: ` ${ duration } ms` ,
status: response . status
}
})
Logging Best Practices
Structured Logging
Use consistent log formats:
// Good: Structured with context
console . log ( 'Market created' , {
marketId: market . id ,
creator: market . creator ,
endDate: market . endDate ,
type: market . type
})
// Bad: Unstructured string
console . log ( `Created market ${ market . id } ` )
Log Levels
Use appropriate log levels:
// Info: Normal operations
console . log ( 'User logged in' , { userId: user . id })
// Warning: Recoverable issues
console . warn ( 'API rate limit approaching' , {
remaining: rateLimitRemaining ,
resetAt: rateLimitReset
})
// Error: Failures requiring attention
console . error ( 'Failed to sync resolution' , {
error: error . message ,
marketId: market . id
})
Sensitive Data
Never log sensitive information:
// Bad: Logs API keys
console . log ( 'API key:' , process . env . KUEST_API_KEY )
// Good: Logs masked version
console . log ( 'API key configured:' , Boolean ( process . env . KUEST_API_KEY ))
// Bad: Logs user email
console . log ( 'User email:' , user . email )
// Good: Logs user ID only
console . log ( 'User:' , { id: user . id })
Alerting
Sentry Alerts
Configure alerts in Sentry dashboard:
Error Rate Alerts
Alert when error rate exceeds threshold:
Trigger: > 10 errors in 5 minutes
Notify: Email, Slack, PagerDuty
Performance Degradation
Alert on slow transactions:
Trigger: P95 latency > 3 seconds
Notify: Slack channel
Cron Job Failures
Alert when scheduled tasks fail:
Trigger: Cron job returns error status
Notify: On-call engineer
User Impact
Alert on issues affecting multiple users:
Trigger: Same error from > 10 users
Notify: Team lead
Custom Alerts
Implement application-level alerts:
// Monitor critical operations
async function monitorCriticalOperation (
operationName : string ,
operationFn : () => Promise < void >
) {
try {
await operationFn ()
} catch ( error ) {
// Send immediate alert
Sentry . captureException ( error , {
level: 'fatal' ,
tags: { critical: 'true' , operation: operationName }
})
// Additional notification channels
await sendSlackAlert ({
channel: '#critical-alerts' ,
message: `Critical operation failed: ${ operationName } ` ,
error: error . message
})
throw error
}
}
// Usage
await monitorCriticalOperation (
'resolution_sync' ,
() => syncResolutions ()
)
Debugging
Error Context
Access full error context in Sentry:
Stack Trace : See where the error occurred
Breadcrumbs : User actions leading to the error
User Context : Who experienced the issue
Environment : Browser, OS, app version
Request Data : URL, headers, body
Source Maps
Debug minified production code:
# Sentry automatically uploads source maps during build
npm run build
# Verify source maps in Sentry dashboard
# Navigate to: Settings > Projects > [Your Project] > Source Maps
Replay Sessions
Enable session replay for visual debugging:
// sentry.client.config.ts
Sentry . init ({
dsn: process . env . NEXT_PUBLIC_SENTRY_DSN ,
integrations: [
new Sentry . Replay ({
maskAllText: true ,
blockAllMedia: true ,
}),
],
replaysSessionSampleRate: 0.1 ,
replaysOnErrorSampleRate: 1.0 ,
})
Monitoring Checklist
Troubleshooting
Sentry Not Capturing Errors
Issue : Errors occur but don’t appear in Sentry.
Solution :
Verify SENTRY_DSN is set in environment variables
Check Sentry initialization in instrumentation.ts
Ensure errors are not caught without re-throwing
Verify network connectivity to Sentry servers
Check browser console for Sentry initialization errors
Source Maps Not Working
Issue : Stack traces show minified code.
Solution :
Verify SENTRY_AUTH_TOKEN is configured
Check build logs for source map upload
Ensure sentry.properties file exists
Verify organization and project names match
Re-upload source maps manually if needed:
npx @sentry/cli sourcemaps upload --org=your-org --project=your-project .next
High Error Volume
Issue : Too many errors flooding Sentry.
Solution :
Identify and fix the most common error first
Add error grouping rules in Sentry
Implement rate limiting on error capture
Filter out known non-critical errors
Use beforeSend to sample errors:
Sentry . init ({
beforeSend ( event ) {
// Only send 10% of low-severity errors
if ( event . level === 'warning' && Math . random () > 0.1 ) {
return null
}
return event
}
})
Issue : Monitoring impacting app performance.
Solution :
Reduce tracesSampleRate (e.g., 0.01 for 1%)
Disable session replay on low-end devices
Limit breadcrumb collection
Use edge runtime for critical paths
Implement sampling strategies
Sentry Documentation Official Sentry Next.js integration guide
Admin Panel Monitor platform operations
Resolution Sync Monitor resolution synchronization
Deployment Production deployment best practices