šŸŽ‰ svc-infra v1.0 is here — Production-ready backend infrastructure
What's new
Nfrax Docs logoNfrax Docs

Infrastructure that just works. Ship products, not boilerplate.

Frameworks

  • svc-infra
  • ai-infra
  • fin-infra
  • robo-infra

Resources

  • Getting Started
  • What's New
  • Contributing

Community

  • GitHub

Ā© 2026 nfrax. All rights reserved.

Nfrax Docs logoNfrax Docs
Start HereWhat's New
GitHub
svc-infra

Error Handling Guide

View source

This guide documents the exception hierarchies and error handling patterns in svc-infra.

Exception Hierarchy

code
Exception
└── SvcInfraError (base for all svc-infra exceptions)
    ā”œā”€ā”€ ConfigurationError
    │   └── MissingSecretError
    ā”œā”€ā”€ AuthenticationError
    │   ā”œā”€ā”€ InvalidCredentialsError
    │   ā”œā”€ā”€ TokenExpiredError
    │   └── SessionNotFoundError
    ā”œā”€ā”€ AuthorizationError
    │   └── InsufficientPermissionsError
    ā”œā”€ā”€ DatabaseError
    │   ā”œā”€ā”€ ConnectionError
    │   ā”œā”€ā”€ QueryError
    │   └── MigrationError
    ā”œā”€ā”€ CacheError
    │   ā”œā”€ā”€ CacheConnectionError
    │   └── CacheMissError
    ā”œā”€ā”€ StorageError
    │   ā”œā”€ā”€ FileNotFoundError
    │   └── UploadError
    ā”œā”€ā”€ RateLimitError
    ā”œā”€ā”€ ValidationError
    └── WebhookError
        ā”œā”€ā”€ SignatureVerificationError
        └── DeliveryError

Best Practices

1. Catch Specific Exceptions

python
from svc_infra.exceptions import (
    AuthenticationError,
    TokenExpiredError,
    CacheError,
)

try:
    user = await authenticate(token)
except TokenExpiredError:
    # Handle expired token specifically
    return redirect_to_login()
except AuthenticationError:
    # Handle other auth errors
    raise HTTPException(status_code=401)

2. Never Silently Swallow Exceptions

python
#  WRONG
try:
    risky_operation()
except Exception:
    pass

#  CORRECT
try:
    risky_operation()
except SpecificError as e:
    logger.warning(f"Operation failed: {e}")
    # Handle or re-raise

3. Add Context When Re-Raising

python
try:
    result = external_api.call()
except ExternalAPIError as e:
    raise DatabaseError(f"Failed to sync data: {e}") from e

4. Use Error Codes for API Responses

python
class APIError:
    INVALID_TOKEN = "auth.invalid_token"
    EXPIRED_TOKEN = "auth.expired_token"
    RATE_LIMITED = "rate.limit_exceeded"

# In response:
{
    "error": {
        "code": "auth.expired_token",
        "message": "Your session has expired. Please log in again."
    }
}

HTTP Status Code Mapping

ExceptionHTTP Status
ValidationError400
AuthenticationError401
AuthorizationError403
NotFoundError404
RateLimitError429
DatabaseError500
ConfigurationError500

Logging Errors

python
import logging

logger = logging.getLogger(__name__)

try:
    process_request(data)
except ValidationError as e:
    # User error - log at WARNING
    logger.warning(f"Invalid request: {e}")
    raise
except DatabaseError as e:
    # System error - log at ERROR with stack trace
    logger.error(f"Database error: {e}", exc_info=True)
    raise
except Exception as e:
    # Unexpected - log at CRITICAL
    logger.critical(f"Unexpected error: {e}", exc_info=True)
    raise

Retry Patterns

python
from tenacity import retry, stop_after_attempt, wait_exponential

@retry(
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=1, max=10),
    retry=retry_if_exception_type(TransientError),
)
async def call_external_api():
    return await api.request()

On This Page

Error Handling GuideException HierarchyBest Practices1. Catch Specific Exceptions2. Never Silently Swallow Exceptions3. Add Context When Re-Raising4. Use Error Codes for API ResponsesHTTP Status Code MappingLogging ErrorsRetry Patterns