Error Tracking
ZeroDrag includes Sentry for production error tracking and monitoring.
What This System Does
Sentry tracks errors across your application:
| Category | What's Captured |
|---|---|
| React Errors | Component crashes, render failures |
| API Errors | Route handler exceptions, unexpected failures |
| Stripe Webhooks | Payment processing errors, webhook failures |
| Auth Failures | OAuth errors, magic link delivery issues |
| Email Failures | Resend API errors, delivery failures |
| Server Errors | Database errors, unexpected exceptions |
Why It Exists
Production errors need visibility. Sentry provides real-time error tracking with context, stack traces, and user information to help you debug issues quickly in production.
When You Need to Care About It
You'll interact with error tracking when:
- Debugging production errors
- Adding custom error handling to your features
- Monitoring error rates and patterns
- Configuring error filtering or sampling
Setup
1. Get Sentry DSN
- Create account at sentry.io
- Create a new project (Next.js)
- Copy your DSN (looks like
https://xxx@xxx.ingest.sentry.io/xxx)
2. Configure Environment Variables
Add to .env:
# Sentry Error Tracking
SENTRY_ENVIRONMENT=development
# Server-side error tracking
SENTRY_DSN=https://1234567890abcdef1234567890abcdef@o123456.ingest.sentry.io/1234567
# Client-side error tracking
NEXT_PUBLIC_SENTRY_DSN=https://1234567890abcdef1234567890abcdef@o123456.ingest.sentry.io/1234567Production:
SENTRY_ENVIRONMENT=production
SENTRY_DSN=https://your-real-dsn@o123456.ingest.sentry.io/1234567
NEXT_PUBLIC_SENTRY_DSN=https://your-real-dsn@o123456.ingest.sentry.io/12345673. Verify Setup
The app works fine without Sentry configured. If SENTRY_DSN is missing, error tracking is disabled but the app functions normally.
Configuration Files
| File | Purpose |
|---|---|
| sentry.client.config.ts | Client-side error tracking (React) |
| sentry.server.config.ts | Server-side error tracking (API routes) |
| sentry.edge.config.ts | Edge runtime error tracking (Middleware) |
These files are marked 🔒 CORE SYSTEM - do not modify.
What Gets Filtered
Sentry automatically removes sensitive data:
- Cookies
- Authorization headers
- Stripe signatures
- Environment variables
- Auth tokens
Common Errors You'll See
Stripe Webhook Failures
What it means: Payment processing failed
Where to look:
- Sentry → Issues → Search "stripe_webhook"
- Check subscription ID and customer ID in context
- Verify webhook secret is correct
Fix:
- Check Stripe Dashboard → Webhooks → Logs
- Verify
STRIPE_WEBHOOK_SECRETmatches - Ensure webhook URL is correct
Email Delivery Failures
What it means: Email failed to send (magic link, welcome, etc.)
Where to look:
- Sentry → Issues → Search "resend" or "email"
- Check Resend Dashboard for delivery status
Fix:
- Verify
RESEND_API_KEYis valid - Check sender domain is verified in Resend
- Verify
EMAIL_FROMis correct
Auth Errors
What it means: Google OAuth or magic link failed
Where to look:
- Sentry → Issues → Filter by "auth"
- Check error message for details
Fix:
- Verify Google OAuth credentials
- Check redirect URIs match exactly
- Verify
AUTH_SECRETis set
Database Errors
What it means: Database query failed
Where to look:
- Sentry → Issues → Search "prisma"
- Check database connection
Fix:
- Verify
DATABASE_URLis correct - Ensure database is running
- Check if schema is up to date:
pnpm db:push
Using Error Tracking in Your Code
API Routes
Use the error handler wrapper:
import { withErrorHandler } from "@/lib/error-handler";
export async function POST(request: NextRequest) {
return withErrorHandler(
async () => {
// Your logic here
return NextResponse.json({ success: true });
},
{
context: "my-feature",
tags: { feature: "custom" },
}
);
}Expected Errors
For validation or expected errors, don't use Sentry:
import { createErrorResponse } from "@/lib/error-handler";
// This won't send to Sentry (expected error)
if (!isValid) {
return createErrorResponse("Invalid input", 400);
}Background Operations
For non-critical errors:
import { captureError } from "@/lib/error-handler";
try {
await backgroundTask();
} catch (error) {
// Log to Sentry but don't throw
captureError(error, "background-task");
}Logging
Use the logger for structured logging:
import { logger } from "@/lib/logger";
// Info (console only, not Sentry)
logger.info("User logged in", {
context: "auth",
userId: "123",
});
// Warning (console + Sentry)
logger.warn("Slow API response", {
context: "api",
metadata: { duration: 5000 },
});
// Error (console + Sentry)
logger.error(new Error("Failed"), {
context: "payment",
userId: "123",
});Performance Monitoring
Sentry includes performance monitoring with:
- Development: 100% (all requests)
- Production: 10% (1 in 10 requests)
This keeps quota usage reasonable while still catching issues.
Debugging Production Errors
- Find the Error: Go to Sentry Dashboard → Issues tab → Sort by frequency or last seen
- Check Context: Event ID, User ID (if available), Tags (context, type), Breadcrumbs (what led to the error)
- Reproduce Locally: Use error message and stack trace, check if error exists in development, add more logging if needed
- Fix and Deploy: Fix the issue, deploy to production, mark as resolved in Sentry
Disabling Sentry
To disable error tracking:
- Remove from `.env`:bash
# Comment out or delete # SENTRY_DSN=... # NEXT_PUBLIC_SENTRY_DSN=... - App continues working normally - Sentry is optional
Best Practices
✅ Do
- Log unexpected errors to Sentry
- Add context (user ID, feature name)
- Filter sensitive data
- Keep sample rates low in production
❌ Don't
- Log expected validation errors
- Log 404s or auth redirects
- Include sensitive data in error messages
- Over-log (increases quota usage)
Extending Error Tracking
Add Custom Tags
Sentry.setTag("feature", "custom-feature");
Sentry.setTag("plan", "pro");Add User Context
Sentry.setUser({
id: user.id,
email: user.email, // Sentry hashes this
});Add Breadcrumbs
Sentry.addBreadcrumb({
category: "user-action",
message: "User clicked button",
level: "info",
});Cost Management
Sentry has usage limits on free tier:
- Free: 5,000 errors/month
- Team: 50,000 errors/month+
To manage quota:
- Lower sample rates (already done)
- Filter noisy errors (already configured)
- Upgrade plan if needed
Important Files
sentry.*.config.tsSentry configuration
🔒 CORE - Do not modify
/lib/error-handler.tsAPI error handling
🔒 CORE - Do not modify
/lib/logger.tsStructured logging
🔒 CORE - Do not modify
Related Sections
- Environment Variables - Sentry configuration
- Deployment - Production setup