tedowski's picture
n8n-improvements (#1)
dbe78dd verified
"""Global error handling middleware."""
from fastapi import Request, HTTPException
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException as StarletteHTTPException
import logging
import traceback
import re
logger = logging.getLogger(__name__)
def redact_sensitive_data(data: str) -> str:
"""Redact sensitive information from logs."""
# Redact Authorization headers
data = re.sub(r'(Authorization["\']?:\s*["\']?Bearer\s+)[^\s"\']+', r'\1***', data, flags=re.IGNORECASE)
# Redact bearer tokens in any form
data = re.sub(r'(bearer["\']?:\s*["\']?)[^\s"\']+', r'\1***', data, flags=re.IGNORECASE)
# Redact JWT tokens (3 base64 parts separated by dots)
data = re.sub(r'\b[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b', '***JWT***', data)
return data
async def http_exception_handler(request: Request, exc: HTTPException):
"""Handle HTTP exceptions."""
return JSONResponse(
status_code=exc.status_code,
content={
"error": exc.detail,
"code": f"HTTP_{exc.status_code}"
}
)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
"""Handle validation errors."""
errors = []
for error in exc.errors():
field = ".".join(str(x) for x in error["loc"])
errors.append(f"{field}: {error['msg']}")
return JSONResponse(
status_code=422,
content={
"error": "Validation failed",
"details": "; ".join(errors),
"code": "VALIDATION_ERROR"
}
)
async def general_exception_handler(request: Request, exc: Exception):
"""Handle unexpected exceptions."""
# Redact sensitive data from error messages and traceback
error_msg = redact_sensitive_data(str(exc))
sanitized_traceback = redact_sensitive_data(traceback.format_exc())
logger.error(f"Unexpected error: {error_msg}\n{sanitized_traceback}")
return JSONResponse(
status_code=500,
content={
"error": "Internal server error",
"details": "An unexpected error occurred",
"code": "INTERNAL_ERROR"
}
)
def register_exception_handlers(app):
"""Register all exception handlers with the app."""
app.add_exception_handler(HTTPException, http_exception_handler)
app.add_exception_handler(RequestValidationError, validation_exception_handler)
app.add_exception_handler(Exception, general_exception_handler)