Practice and reinforce the concepts from Lesson 4
By the end of this workshop, you will:
Analyze these production-level errors using AI-assisted debugging:
# Production Error Log
ERROR 2024-01-15 14:32:45 - ConnectionPoolError: Unable to acquire connection
Traceback (most recent call last):
File "/app/services/user_service.py", line 45, in get_user_data
conn = await self.pool.acquire(timeout=5.0)
asyncpg.pool.PoolConnectionError: failed to acquire connection within 5.0 seconds
Investigation Tasks:
// Production Monitoring Alert
CRITICAL: Memory usage exceeded 4GB threshold
Service: api-gateway
Duration: 48 hours continuous operation
Pattern: Linear memory growth ~50MB/hour
// Heap snapshot analysis
{
"arrays": { "count": 2847293, "size": "2.1GB" },
"closures": { "count": 984732, "size": "890MB" },
"detachedNodes": { "count": 458291, "size": "412MB" }
}
Profiling Requirements:
Create a comprehensive error classification system:
Error Category | Indicators | Root Cause Analysis | Resolution Time | Prevention Strategy |
---|---|---|---|---|
Connection Errors | Timeouts, refused connections | Network, firewall, pool exhaustion | 15-30 min | Connection pooling, retry logic |
Memory Issues | OOM errors, slow GC | Leaks, inefficient algorithms | 1-4 hours | Profiling, monitoring |
Concurrency Bugs | Race conditions, deadlocks | Improper synchronization | 2-8 hours | Proper locking, testing |
Data Corruption | Inconsistent state, validation errors | Logic errors, race conditions | 4-16 hours | Transactions, validation |
# Bug: Intermittent duplicate order processing in microservices architecture
# Frequency: ~0.3% of high-volume transactions
# Impact: $45,000 in duplicate charges over 2 weeks
class OrderProcessor:
def __init__(self, db, cache, message_queue):
self.db = db
self.cache = cache
self.queue = message_queue
async def process_order(self, order_id, user_id, items):
# Check if order already processed
if await self.cache.get(f"order:{order_id}"):
return {"status": "already_processed"}
# Process payment
payment_result = await self.process_payment(user_id, items)
# Mark as processed
await self.cache.set(f"order:{order_id}", "processed", ttl=3600)
# Save to database
await self.db.save_order(order_id, user_id, items, payment_result)
# Send confirmation
await self.queue.publish("order.confirmed", {"order_id": order_id})
return {"status": "success", "order_id": order_id}
Root Cause Analysis
Performance Impact Assessment
Implementation Strategy
"Analyze this distributed system code for race conditions and suggest fixes that maintain high throughput"
"Generate a comprehensive test suite for concurrent order processing with edge cases"
"Design a distributed locking mechanism that won't impact performance at 10,000 TPS"
// Alert: API endpoint response time degraded
// Endpoint: GET /api/v2/search
// Normal: 150ms p99 | Current: 2.3s p99
// Traffic: No significant increase
class SearchService {
constructor(database, elasticSearch) {
this.db = database;
this.es = elasticSearch;
this.cache = new Map();
}
async search(query, filters, page = 1, limit = 20) {
// Check cache
const cacheKey = JSON.stringify({ query, filters, page, limit });
if (this.cache.has(cacheKey)) {
return this.cache.get(cacheKey);
}
// Build complex query
const esQuery = this.buildElasticQuery(query, filters);
// Execute search
const results = await this.es.search({
index: 'products',
body: esQuery,
from: (page - 1) * limit,
size: limit
});
// Enrich with database data
const enrichedResults = await Promise.all(
results.hits.hits.map(async (hit) => {
const dbData = await this.db.query(
'SELECT * FROM products WHERE id = $1',
[hit._id]
);
return { ...hit._source, ...dbData.rows[0] };
})
);
// Cache results
this.cache.set(cacheKey, enrichedResults);
return enrichedResults;
}
}
Bottleneck Identification
Metrics to collect:
- Query execution time breakdown
- Network latency measurements
- CPU and memory profiles
- Database query analysis
AI-Assisted Analysis Prompts
"Profile this search service code and identify performance bottlenecks"
"Suggest optimizations for the N+1 query problem in this code"
"Design a caching strategy that handles cache invalidation properly"
Optimization Implementation
# Production Error (occurs randomly ~5% of requests)
# Error: "NoneType object has no attribute 'decode'"
# No clear pattern in logs
import jwt
import redis
from datetime import datetime, timedelta
class AuthService:
def __init__(self, redis_client, secret_key):
self.redis = redis_client
self.secret = secret_key
def verify_token(self, token):
try:
# Decode JWT
payload = jwt.decode(token, self.secret, algorithms=['HS256'])
user_id = payload.get('user_id')
# Check if token is blacklisted
is_blacklisted = self.redis.get(f'blacklist:{token}')
if is_blacklisted:
raise ValueError("Token has been revoked")
# Get user session
session_data = self.redis.get(f'session:{user_id}')
session = session_data.decode('utf-8')
# Validate session
if not session:
raise ValueError("Invalid session")
return {
'user_id': user_id,
'session': session,
'valid': True
}
except jwt.ExpiredSignatureError:
return {'valid': False, 'error': 'Token expired'}
except Exception as e:
return {'valid': False, 'error': str(e)}
Reproduce the Issue
Root Cause Analysis
Robust Solution Design
Fix this code that should validate email addresses but has multiple issues:
function validateEmail(email) {
const pattern = "@.";
if (email.includes(pattern)) {
return true;
}
if (email.length > 5) {
return true;
}
return false;
}
// All of these should work correctly:
console.log(validateEmail("user@example.com")); // Should be true
console.log(validateEmail("invalid.email")); // Should be false
console.log(validateEmail("@example.com")); // Should be false
console.log(validateEmail("user@")); // Should be false
Debug this React-like component logic:
let todos = [];
let currentId = 0;
function addTodo(text) {
const todo = {
id: currentId,
text: text,
completed: false
};
todos.push(todo);
currentId++;
}
function toggleTodo(id) {
const todo = todos.find(t => t.id === id);
todo.completed = !todo.completed;
}
function deleteTodo(id) {
todos = todos.filter(t => t.id != id);
}
// Bug: After deleting, toggle doesn't work for some todos
addTodo("First");
addTodo("Second");
addTodo("Third");
deleteTodo(1);
toggleTodo(2); // This might fail!
Debug this async code:
async function fetchUserData(userId) {
const user = await fetch(`/api/users/${userId}`);
const posts = await fetch(`/api/posts?userId=${userId}`);
return {
user: user.json(),
posts: posts.json()
};
}
// This doesn't work as expected
fetchUserData(1).then(data => {
console.log(data.user); // Prints Promise, not data!
});
This function has hidden edge cases. Find and fix them all:
def parse_time(time_string):
# Expected format: "HH:MM:SS"
parts = time_string.split(":")
hours = int(parts[0])
minutes = int(parts[1])
seconds = int(parts[2])
total_seconds = hours * 3600 + minutes * 60 + seconds
return total_seconds
# Find edge cases that break this
Practice explaining bugs to AI as if it were a rubber duck:
Template:
I have a function that should [expected behavior].
Currently, it [actual behavior].
The code does [step-by-step explanation].
I think the problem might be [hypothesis].
Use AI to help you:
Process:
Bug Discovered
ā
[Your Step 1] ā [Your Step 2] ā [Your Step 3]
ā
Bug Fixed & Tested
Identify patterns you've noticed:
Most Common Bug Types:
Most Effective AI Prompts for Debugging:
Signs You Should Use AI vs. Debug Yourself:
Build your personal debugging checklist:
Create a collection of debugging tools with AI:
Error Message Translator
Code Trace Visualizer
Test Case Generator
Performance Profiler Helper
Document your most challenging debug:
ā Syntax errors and typos ā Common logic errors ā Performance optimization ā Understanding error messages ā Generating test cases
ā ļø Complex business logic ā ļø Race conditions ā ļø Environment-specific issues ā ļø Security vulnerabilities ā ļø Legacy code interactions
Your debugging portfolio should include:
Our final lesson covers best practices and ethics in AI-assisted coding. Start thinking about the implications of AI in software development and how to use it responsibly!