Build Debug Tools
Create custom debugging utilities for your stack
Ta treść nie jest jeszcze dostępna w Twoim języku.
Production is down. Users report that checkout fails intermittently with a vague “Transaction failed” error. It works fine in development, happens only under load, and started after last week’s deployment. The error rate is 15% and growing. Your CEO is asking for updates every 30 minutes.
By completing this lesson, you’ll master:
Debug a complex production issue involving:
Start with Ask mode to analyze available information:
"Help me create a systematic debugging plan for:- Error: 'Transaction failed' during checkout- Frequency: 15% of transactions- Started: After deployment on [date]- Pattern: Only under load, works in devWhat information should I gather first?"
@logs/production-errors.log"Analyze these error logs:- Find patterns in failed transactions- Identify common characteristics- Look for timing patterns- Check for correlated errors- Extract unique error signatures"
@git log --since="1 week ago" --oneline"Review recent commits that could cause:- Race conditions- Performance issues- Database deadlocks- Payment processing changesFocus on checkout and payment flows"
Switch to Agent mode:
@logs/errors.log @src/checkout @src/payment"Based on the symptoms and code, generate hypotheses for:- Why it only fails under load- Why error message is generic- Possible race conditions- Database connection issuesRank by probability"
"Create a detailed investigation plan for top 3 hypotheses:1. What to look for in logs2. Queries to run on database3. Metrics to check4. Code paths to trace5. Tests to write"
@src/checkout/service.js @src/payment/processor.js"Trace a complete checkout transaction:- Create sequence diagram- Identify all external calls- Mark async operations- Find potential race conditions- Note error handling gaps"
"Create a load test to reproduce the issue:- Simulate production traffic patterns- Include concurrent checkouts- Vary payment amounts and methods- Add network latency- Monitor for the exact error"
Example load test:
import { check } from 'k6';import http from 'k6/http';
export const options = { stages: [ { duration: '30s', target: 100 }, { duration: '1m', target: 200 }, { duration: '30s', target: 0 }, ], thresholds: { http_req_failed: ['rate < 0.1'], // Less than 10% errors http_req_duration: ['p(95) < 500'], // 95% under 500ms },};
export default function() { const payload = JSON.stringify({ items: [{ id: 1, quantity: 2 }], payment: { method: 'credit_card', amount: Math.random() * 1000, }, });
const response = http.post( 'http://localhost:3000/api/checkout', payload, { headers: { 'Content-Type': 'application/json' } } );
check(response, { 'status is 200': (r) => r.status === 200, 'no transaction error': (r) => !r.body.includes('Transaction failed'), });}
@src/checkout/service.js"Add comprehensive debug logging:- Transaction start/end times- Database query durations- External API call times- Lock acquisition/release- Connection pool statsUse structured logging with correlation IDs"
"Create minimal code to reproduce the issue:- Remove unnecessary complexity- Focus on the failing path- Make it deterministic if possible- Add timing controls- Document reproduction steps"
@logs/debug-trace.log"Analyze transaction timings:- Find operations taking too long- Identify concurrent operations- Look for lock contention- Check timeout configurations- Correlate with failures"
-- AI generates diagnostic queries"Generate SQL queries to investigate:- Deadlocks in the payment table- Long-running transactions- Connection pool exhaustion- Lock wait timeouts- Index usage statistics"
Based on investigation, AI helps identify:
// Root cause found: Database connection pool exhaustion// Old code:async function processPayment(paymentData) { const conn = await db.getConnection(); try { await conn.beginTransaction();
// Bug: Connection not released on early return if (!validatePayment(paymentData)) { return { error: 'Transaction failed' }; // Connection leaked! }
const result = await conn.query('INSERT INTO payments...'); await conn.commit(); return result; } catch (error) { await conn.rollback(); throw error; } finally { conn.release(); // Not reached on validation failure }}
@src/payment/processor.js"Fix the connection leak issue:- Ensure connections always released- Add connection pool monitoring- Improve error messages- Add circuit breaker pattern- Include correlation IDs"
Fixed code:
async function processPayment(paymentData) { const conn = await db.getConnection(); try { // Validate before transaction if (!validatePayment(paymentData)) { return { error: 'Payment validation failed', details: getValidationErrors(paymentData), correlationId: generateCorrelationId() }; }
await conn.beginTransaction();
const result = await conn.query('INSERT INTO payments...', paymentData); await conn.commit();
logger.info('Payment processed successfully', { paymentId: result.insertId, correlationId: paymentData.correlationId });
return { success: true, paymentId: result.insertId }; } catch (error) { await conn.rollback(); logger.error('Payment processing failed', { error: error.message, stack: error.stack, paymentData, correlationId: paymentData.correlationId }); throw new PaymentError('Transaction failed', error); } finally { // Always release connection conn.release(); }}
"Add comprehensive monitoring:- Connection pool metrics- Transaction duration histogram- Error rate by type- Queue depth monitoring- Alert thresholds"
@src/payment/processor.test.js"Create tests for the bug:- Test connection leak scenario- Test under concurrent load- Test error handling- Test monitoring metrics- Test circuit breaker"
Follow this proven pattern:
Narrow down the problem:
// Start wide"The checkout process is failing"
// Narrow to subsystem"The payment processing is failing"
// Narrow to specific operation"Database connections are leaking during validation"
// Find exact line"Line 47: early return without connection release"
Use git bisect with AI:
# AI helps create test script@src/checkout"Create a script that returns 0 if checkout works, 1 if it fails"
# Use git bisectgit bisect startgit bisect bad HEADgit bisect good abc123git bisect run ./test-checkout.sh
"Analyze this code for race conditions:- Identify shared resources- Find missing synchronization- Look for check-then-act patterns- Suggest fixes with proper locking"
"Help me find memory leaks:- Analyze heap dumps- Find circular references- Identify unclosed resources- Suggest cleanup patterns"
"Profile this slow operation:- Add timing measurements- Find N+1 queries- Identify CPU bottlenecks- Suggest optimizations"
Level up your debugging skills:
Distributed Tracing
Chaos Engineering
AI-Powered Monitoring
Track your debugging effectiveness:
“Used Cursor to analyze 50K lines of logs in minutes, found the circular dependency that only occurred when orders exceeded $9,999.99”
“AI identified a WebSocket event listener that wasn’t cleaned up on reconnection, causing 10MB/hour memory growth”
“Discovered cache stampede pattern when all user sessions expired simultaneously at week start”
Essential tools integrated with Cursor:
## Quick Commands
### Analyze Logs@logs/production.log "Find anomalies in the last hour"
### Check Performance@src/slow-endpoint.js "Profile and find bottlenecks"
### Trace Execution@src "Trace execution path for user ID 12345"
### Find Similar Issues@git log --grep="Transaction failed" "Show how similar issues were fixed"
You’ve mastered systematic debugging. Ready for more?
Build Debug Tools
Create custom debugging utilities for your stack
Teach Others
Run a debugging workshop for your team
Contribute
Share your debugging patterns with the community
Continue to API Integration →