| name | error-tracking |
| description | Add Sentry v8 error tracking and performance monitoring to your project services. Use this skill when adding error handling, creating new controllers, instrumenting cron jobs, or tracking database performance. ALL ERRORS MUST BE CAPTURED TO SENTRY - no exceptions. |
| triggers | ["sentry","error tracking","captureException","monitoring","performance tracking","error handling","sentry integration"] |
Sentry v8 Error Tracking & Performance Monitoring
Purpose
This skill enforces comprehensive Sentry error tracking and performance monitoring across all services following Sentry v8 patterns.
When to Use This Skill
- Adding error handling to any code
- Creating new controllers or routes
- Instrumenting cron jobs
- Tracking database performance
- Adding performance spans
- Handling workflow errors
CRITICAL RULE
ALL ERRORS MUST BE CAPTURED TO SENTRY - No exceptions. Never use console.error alone.
Sentry Integration Patterns
1. Controller Error Handling
import { BaseController } from '../controllers/BaseController';
export class MyController extends BaseController {
async myMethod() {
try {
} catch (error) {
this.handleError(error, 'myMethod');
}
}
}
2. Route Error Handling (Without BaseController)
import * as Sentry from '@sentry/node';
router.get('/route', async (req, res) => {
try {
} catch (error) {
Sentry.captureException(error, {
tags: { route: '/route', method: 'GET' },
extra: { userId: req.user?.id }
});
res.status(500).json({ error: 'Internal server error' });
}
});
3. Workflow Error Handling
import * as Sentry from '@sentry/node';
Sentry.withScope((scope) => {
scope.setTag('workflow', 'order-processing');
scope.setTag('step', 'payment');
scope.setContext('workflow', {
instanceId: 123,
stepId: 456,
userId: 'user-123',
operation: 'stepCompletion',
});
Sentry.captureException(error);
});
4. Cron Jobs (MANDATORY Pattern)
#!/usr/bin/env node
import '../instrument';
import * as Sentry from '@sentry/node';
async function main() {
return await Sentry.startSpan({
name: 'cron.job-name',
op: 'cron',
attributes: {
'cron.job': 'job-name',
'cron.startTime': new Date().toISOString(),
}
}, async () => {
try {
} catch (error) {
Sentry.captureException(error, {
tags: {
'cron.job': 'job-name',
'error.type': 'execution_error'
}
});
console.error('[Job] Error:', error);
process.exit(1);
}
});
}
main()
.then(() => {
console.log('[Job] Completed successfully');
process.exit(0);
})
.catch((error) => {
console.error('[Job] Fatal error:', error);
process.exit(1);
});
5. Database Performance Monitoring
import * as Sentry from '@sentry/node';
const result = await Sentry.startSpan({
name: 'db.findMany',
op: 'db.query',
attributes: {
'db.system': 'postgresql',
'db.operation': 'findMany',
'db.table': 'user_profile',
}
}, async () => {
return await prisma.userProfile.findMany({ take: 5 });
});
6. Async Operations with Spans
import * as Sentry from '@sentry/node';
const result = await Sentry.startSpan({
name: 'operation.name',
op: 'operation.type',
attributes: {
'custom.attribute': 'value'
}
}, async () => {
return await someAsyncOperation();
});
Error Levels
Use appropriate severity levels:
- fatal: System is unusable (database down, critical service failure)
- error: Operation failed, needs immediate attention
- warning: Recoverable issues, degraded performance
- info: Informational messages, successful operations
- debug: Detailed debugging information (dev only)
Required Context
import * as Sentry from '@sentry/node';
Sentry.withScope((scope) => {
scope.setUser({ id: userId });
scope.setTag('service', 'api');
scope.setTag('environment', process.env.NODE_ENV);
scope.setContext('operation', {
type: 'workflow.start',
workflowCode: 'ORDER_PROCESSING',
entityId: 123
});
Sentry.captureException(error);
});
Integration Examples
Node.js / Express Initialization
Location: src/instrument.ts
import * as Sentry from '@sentry/node';
import { nodeProfilingIntegration } from '@sentry/profiling-node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV || 'development',
integrations: [
nodeProfilingIntegration(),
],
tracesSampleRate: 0.1,
profilesSampleRate: 0.1,
});
Express Setup (Sentry v8):
import * as Sentry from '@sentry/node';
import express from 'express';
const app = express();
Sentry.setupExpressErrorHandler(app);
Key Helpers (Recommended Structure)
src/instrument.ts - Sentry initialization (import first!)
src/utils/sentryHelper.ts - Domain-specific error helpers
src/utils/databasePerformance.ts - DB query tracking
src/controllers/BaseController.ts - Controller error handling base
Configuration
[sentry]
dsn = your-sentry-dsn
environment = development
tracesSampleRate = 0.1
profilesSampleRate = 0.1
[databaseMonitoring]
enableDbTracing = true
slowQueryThreshold = 100
logDbQueries = false
dbErrorCapture = true
enableN1Detection = true
Testing Sentry Integration
curl http://localhost:3000/api/sentry/test-error
curl http://localhost:3000/api/sentry/test-performance
curl http://localhost:3000/api/sentry/test-database-performance
After running test endpoints, verify in Sentry dashboard:
- Error appears in Issues with correct tags
- Performance transaction recorded with spans
- User context and tags attached correctly
Performance Monitoring
Requirements
- All API endpoints must have transaction tracking
- Database queries > 100ms are automatically flagged
- N+1 queries are detected and reported
- Cron jobs must track execution time
Transaction Tracking (Sentry v8)
import * as Sentry from '@sentry/node';
const result = await Sentry.startSpan({
op: 'operation.type',
name: 'Operation Name',
}, async (span) => {
return await Sentry.startSpan({
op: 'db.query',
name: 'Fetch user data',
}, async () => {
return await fetchUserData();
});
});
Anti-Patterns
1. catch ๋ธ๋ก์์ Sentry ๋ฏธ์ ์ก
try {
await riskyOperation();
} catch (error) {
console.error(error);
}
try {
await riskyOperation();
} catch (error) {
Sentry.captureException(error);
throw error;
}
2. ์ ์ญ try-catch๋ก ๋ชจ๋ ์๋ฌ ๋ญ๊ฐ๊ธฐ
app.use(async (req, res, next) => {
try {
await next();
} catch (e) {
res.status(200).json({ ok: true });
}
});
app.use(async (req, res, next) => {
try {
await next();
} catch (error) {
Sentry.captureException(error, {
tags: { route: req.path, method: req.method },
});
res.status(500).json({ error: 'Internal server error' });
}
});
3. PII ๋ฐ์ดํฐ Sentry ์ ์ก
Sentry.setUser({ email: user.email, password: user.password, ssn: user.ssn });
Sentry.setUser({ id: user.id });
4. deprecated startTransaction ์ฌ์ฉ
const transaction = Sentry.startTransaction({ op: 'task', name: 'My Task' });
try { } finally { transaction.finish(); }
await Sentry.startSpan({ op: 'task', name: 'My Task' }, async () => {
});
5. ์๋ฌ ์ปจํ
์คํธ ์์ด ์บก์ฒ
Sentry.captureException(error);
Sentry.captureException(error, {
tags: { service: 'payment', operation: 'charge' },
extra: { orderId: order.id, amount: order.total },
});
6. instrument.ts ์ํฌํธ ์์ ์๋ฐ (Cron Jobs)
import { myService } from '../services/myService';
import '../instrument';
import '../instrument';
import * as Sentry from '@sentry/node';
import { myService } from '../services/myService';
Implementation Checklist
When adding Sentry to new code: