1---2name: error-handling3description: Framework-agnostic error handling patterns including exception hierarchy, error classification, response format, and handling principles. Use when designing error handling strategies.4license: MIT5---6# Error Handling Rules78## 1. Exception Hierarchy910### Business vs System Exceptions1112| Category | Characteristics | HTTP Status Range | Log Level |13| ------------------ | ---------------------------------- | ----------------- | ------------ |14| Business exception | Expected, recoverable by caller | 4xx | WARN or INFO |15| System exception | Unexpected, programming bug or I/O | 5xx | ERROR |1617### Error Classification1819| Type | Examples | Recommended Action |20| -------------- | ------------------------------------ | ------------------------------- |21| Recoverable | Invalid input, network timeout | Signal to caller, allow retry |22| Unrecoverable | Programming bug, corrupted state | Fail fast, log and alert |23| External fault | Upstream API error, DNS failure | Wrap in domain exception, retry |2425---2627## 2. Error Response Format2829### Standard JSON Structure3031```json32{33 "error": {34 "code": "ENTITY_NOT_FOUND",35 "message": "User not found: 42",36 "details": [37 {38 "field": "userId",39 "message": "No user exists with the given ID"40 }41 ]42 },43 "meta": {44 "timestamp": "2024-01-15T10:30:45.123Z",45 "requestId": "abc-123-def"46 }47}48```4950### Response Format Rules5152- Use a consistent error envelope across all endpoints53- Include a machine-readable error code (not just HTTP status)54- Include a human-readable message for debugging55- Include field-level details for validation errors56- Include requestId/traceId for correlation5758---5960## 3. Exception Handling Principles6162### Do6364- Catch at the appropriate layer (controller for HTTP, service for business logic)65- Always include context in exception messages (entity name, ID, field)66- Log stack traces for system exceptions67- Use error code enums for consistent codes across the application68- Include traceId in error responses for debugging6970### Do Not7172- Catch exceptions broadly in service/repository layers73- Expose internal details (stack traces, SQL, class names) in API responses74- Use exceptions for flow control (e.g., throwing NotFoundException to check existence)75- Swallow exceptions silently (empty catch blocks)76- Log sensitive data in exception messages (passwords, tokens, PII)7778---7980## 4. Layer-Specific Guidelines8182### Controller Layer8384- Do not handle exceptions directly — delegate to a centralized exception handler85- Validate request inputs at the API boundary before passing to service layer8687### Service Layer8889- Throw business exception subtypes for business rule violations90- Wrap external API failures in domain-specific exceptions91- Use explicit try-catch only for recoverable operations9293### Repository / Data Layer9495- Let data access exceptions propagate to the service layer96- Do not catch data access exceptions unless specific recovery logic exists9798---99100## 5. External API Error Handling101102### Principles103104- Never let raw HTTP client exceptions propagate to callers105- Wrap in domain-specific exceptions (e.g., `PaymentApiException`)106- Log response status and body on errors (but mask sensitive data)107- Distinguish between retryable (network, 503) and non-retryable (400, 404) errors108109### Error Wrapping Strategy110111| Exception Source | Cause | Action |112| ----------------------- | ------------------- | ---------------------- |113| HTTP response error | 4xx/5xx response | Map to domain error |114| Network/timeout error | Connection failure | Retry or circuit break |115| Parsing/decoding error | Malformed response | Log and fail |116117---118119## 6. Anti-Patterns120121- Catching generic `Exception` in every method122- Returning error details in success response fields123- Using HTTP 200 for all responses with error codes in body124- Inconsistent error response formats across endpoints125- Missing error codes (only HTTP status, no application code)126- Logging errors without stack traces127- Retrying on non-idempotent failures without safeguards128- **Pokemon Exception Handling**: Catching all exceptions with a generic catch-all. Use specific exception types instead129- **Error Swallowing**: Empty catch blocks make debugging impossible. Always log or propagate errors130- **Exceptions as Flow Control**: Using exceptions for normal program flow degrades performance and readability131132## Additional References133134- For standardized error response formats, RFC 7807 Problem Details, and error code design, see [references/response-schema.md](references/response-schema.md)135- [Microsoft Error Handling Best Practices](https://learn.microsoft.com/en-us/dotnet/standard/exceptions/best-practices-for-exceptions) - .NET exception handling best practices136- [Effective Java - Exceptions](https://www.oreilly.com/library/view/effective-java/9780134686097/) - Java exception handling guide137- For Spring Boot implementation patterns (`@ControllerAdvice`, ErrorCode enum), see `spring-framework` skill — [references/error-handling.md](../spring-framework/references/error-handling.md)