Claude
Skills
Sign in
Back

error-handling-skills

Included with Lifetime
$97 forever

Universal error handling, exception management, and logging best practices for all development agents across JavaScript/TypeScript, Python, Rust, Go, and Java. Use when implementing error handling, exception management, logging, error recovery, or debugging production issues.

Backend & APIs

What this skill does


# Error Handling Skills

## Overview

This skill provides comprehensive error handling, exception management, and logging best practices applicable to all development work. It covers language-agnostic principles and language-specific implementations for JavaScript/TypeScript, Python, Rust, Go, and Java.

Use this skill when:
- Implementing error handling in any application
- Designing exception hierarchies
- Setting up logging infrastructure
- Handling failures and implementing recovery patterns
- Securing error messages and stack traces
- Testing error conditions
- Debugging production issues

## Core Error Handling Philosophy

### 1. Fail Fast vs Graceful Degradation

**Fail Fast** - Immediately stop execution when an error occurs:
- Use for: Critical errors, data corruption, security violations
- Benefits: Prevents cascading failures, maintains data integrity
- Example: Database connection failure, authentication breach, invalid configuration

**Graceful Degradation** - Continue operation with reduced functionality:
- Use for: Non-critical features, external service failures, optional enhancements
- Benefits: Better user experience, higher availability
- Example: Analytics service down, search feature unavailable, image optimization failed

**Decision Matrix**:
```
Critical Path? → Yes → Fail Fast
              → No → Can provide fallback? → Yes → Graceful Degradation
                                          → No → Fail Fast with clear message
```

### 2. Catch vs Propagate Errors

**When to Catch (Handle Locally)**:
- Can meaningfully recover from the error
- Can provide a useful fallback value
- Can add context before re-throwing
- At API/system boundaries (convert internal errors to user-facing)
- In retry/circuit breaker logic

**When to Propagate (Let It Bubble)**:
- Cannot recover or provide meaningful fallback
- Error handling belongs to caller's responsibility
- Preserving original error context is critical
- In library code (let application decide handling)

**Anti-Pattern**: Catching and ignoring errors
```javascript
// ❌ NEVER DO THIS
try {
  await criticalOperation();
} catch (err) {
  // Silent failure - error is lost
}
```

### 3. Error Severity Levels

**CRITICAL** - System failure, immediate attention required:
- Database down, service unreachable, security breach
- Action: Alert on-call, page immediately, log to incident tracking
- User message: "Service unavailable, we're working on it"

**ERROR** - Operation failed, manual intervention may be needed:
- API request failed, file write failed, validation failed
- Action: Log with full context, may trigger alerts if frequent
- User message: Specific actionable message (e.g., "Invalid email format")

**WARNING** - Unexpected but handled condition:
- Deprecated feature used, rate limit approaching, slow query
- Action: Log for monitoring, no immediate action
- User message: Usually none (internal only)

**INFO** - Normal operational events:
- Request started/completed, user logged in, cache hit
- Action: Log for audit/analytics
- User message: None

**DEBUG** - Detailed diagnostic information:
- Variable values, execution flow, intermediate states
- Action: Log only in development/staging
- User message: None

### 4. Error Context and Stack Traces

**Always Include**:
- Timestamp (ISO 8601 format)
- Error type/code
- User-facing message
- Request ID / Correlation ID
- User ID (if authenticated)
- Operation being performed
- Input parameters (sanitized)

**Include in Logs Only (Never Expose to Users)**:
- Full stack trace
- Internal system details
- File paths and line numbers
- Database connection strings
- Environment variables

**Example Error Context**:
```json
{
  "timestamp": "2025-11-14T10:30:45.123Z",
  "level": "ERROR",
  "error_type": "DatabaseConnectionError",
  "message": "Failed to connect to database",
  "request_id": "req_abc123",
  "user_id": "user_789",
  "operation": "create_order",
  "details": {
    "retry_count": 3,
    "last_error": "Connection timeout after 5000ms"
  },
  "stack_trace": "..."  // Internal only
}
```

## Error Handling Patterns by Language

This section provides quick-reference patterns. For detailed implementations and examples, see the language-specific reference files:
- `references/javascript-patterns.md` - JavaScript/TypeScript detailed patterns
- `references/python-patterns.md` - Python detailed patterns
- `references/rust-patterns.md` - Rust detailed patterns
- `references/go-patterns.md` - Go detailed patterns
- `references/java-patterns.md` - Java detailed patterns

### JavaScript/TypeScript Quick Reference

**Synchronous Errors**:
```typescript
try {
  const result = riskyOperation();
  return result;
} catch (error) {
  if (error instanceof ValidationError) {
    return handleValidationError(error);
  }
  throw error; // Propagate unknown errors
} finally {
  cleanup(); // Always runs
}
```

**Async/Await Errors**:
```typescript
try {
  const data = await fetchData();
  return processData(data);
} catch (error) {
  logger.error('Data fetch failed', { error, requestId });
  throw new ServiceError('Unable to fetch data', { cause: error });
}
```

**Promise Rejection**:
```typescript
fetchData()
  .then(processData)
  .catch(error => {
    logger.error('Pipeline failed', { error });
    return fallbackData; // Graceful degradation
  });
```

See `references/javascript-patterns.md` for custom error classes, async error boundaries, and Express/Nest.js patterns.

### Python Quick Reference

**Try-Except-Finally**:
```python
try:
    result = risky_operation()
    return result
except ValueError as e:
    logger.error(f"Validation failed: {e}", exc_info=True)
    raise ValidationError(f"Invalid input: {e}") from e
except Exception as e:
    logger.critical(f"Unexpected error: {e}", exc_info=True)
    raise
finally:
    cleanup()  # Always runs
```

**Context Managers**:
```python
with open('file.txt') as f:
    data = f.read()  # File automatically closed even if error occurs
```

**Custom Exceptions**:
```python
class ApplicationError(Exception):
    """Base exception for application errors"""
    pass

class DatabaseError(ApplicationError):
    """Database operation failed"""
    pass
```

See `references/python-patterns.md` for exception chaining, decorators, and FastAPI/Django patterns.

### Rust Quick Reference

**Result<T, E>**:
```rust
fn read_file(path: &str) -> Result<String, std::io::Error> {
    std::fs::read_to_string(path)
}

// Using ?operator to propagate
fn process() -> Result<(), Box<dyn std::error::Error>> {
    let content = read_file("config.toml")?;
    Ok(())
}
```

**Option<T>**:
```rust
fn find_user(id: u32) -> Option<User> {
    database.get(id)
}

// Using unwrap_or for fallback
let user = find_user(123).unwrap_or_default();
```

**Custom Errors with thiserror**:
```rust
use thiserror::Error;

#[derive(Error, Debug)]
pub enum AppError {
    #[error("Database error: {0}")]
    Database(#[from] sqlx::Error),

    #[error("Validation failed: {0}")]
    Validation(String),
}
```

See `references/rust-patterns.md` for panic vs Result, error conversion, and anyhow patterns.

### Go Quick Reference

**Error Interface**:
```go
func readFile(path string) ([]byte, error) {
    data, err := os.ReadFile(path)
    if err != nil {
        return nil, fmt.Errorf("failed to read %s: %w", path, err)
    }
    return data, nil
}
```

**Error Wrapping**:
```go
import "github.com/pkg/errors"

if err != nil {
    return errors.Wrap(err, "additional context")
}
```

**Defer for Cleanup**:
```go
func process() error {
    f, err := os.Open("file.txt")
    if err != nil {
        return err
    }
    defer f.Close() // Runs when function exits

    // Process file...
    return nil
}
```

See `references/go-patterns.md` for custom error types, sentinel errors, and panic recovery.

### Java Quick Reference

**Try-Catch-Finally**:
```java
try {
    Result result = riskyOperation();
    return result;
} catch (ValidationException e) {
    l

Related in Backend & APIs