Spaces:
Sleeping
Sleeping
Claude Code Claude Opus 4.6 commited on
Commit ·
ba6c66b
1
Parent(s): ce4bc03
Claude Code: Add full traceback logging middleware
Browse files- Import traceback and BaseMiddleware
- Replace function middleware with class-based LoggingMiddleware
- Log full stack trace with traceback.format_exc() on errors
- Return JSONResponse with 500 status instead of re-raising
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
app.py
CHANGED
|
@@ -1,6 +1,8 @@
|
|
| 1 |
import os
|
| 2 |
import logging
|
|
|
|
| 3 |
from fastapi import FastAPI, Request
|
|
|
|
| 4 |
from datetime import datetime
|
| 5 |
from fastapi.responses import JSONResponse
|
| 6 |
from pydantic import BaseModel
|
|
@@ -28,21 +30,29 @@ STARTUP_MODE = os.environ.get("STARTUP_MODE", "minimal")
|
|
| 28 |
app = FastAPI()
|
| 29 |
|
| 30 |
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
|
| 47 |
|
| 48 |
@app.exception_handler(Exception)
|
|
|
|
| 1 |
import os
|
| 2 |
import logging
|
| 3 |
+
import traceback
|
| 4 |
from fastapi import FastAPI, Request
|
| 5 |
+
from starlette.middleware.base import BaseMiddleware
|
| 6 |
from datetime import datetime
|
| 7 |
from fastapi.responses import JSONResponse
|
| 8 |
from pydantic import BaseModel
|
|
|
|
| 30 |
app = FastAPI()
|
| 31 |
|
| 32 |
|
| 33 |
+
class LoggingMiddleware(BaseMiddleware):
|
| 34 |
+
"""Middleware to log all requests and capture full tracebacks on errors."""
|
| 35 |
+
|
| 36 |
+
async def dispatch(self, request: Request, call_next):
|
| 37 |
+
"""Process request with full error logging."""
|
| 38 |
+
start_time = datetime.utcnow()
|
| 39 |
+
logger.info(f"Request: {request.method} {request.url.path}")
|
| 40 |
+
|
| 41 |
+
try:
|
| 42 |
+
response = await call_next(request)
|
| 43 |
+
duration = (datetime.utcnow() - start_time).total_seconds()
|
| 44 |
+
logger.info(f"Response: {response.status_code} - {duration:.3f}s")
|
| 45 |
+
return response
|
| 46 |
+
except Exception as e:
|
| 47 |
+
duration = (datetime.utcnow() - start_time).total_seconds()
|
| 48 |
+
full_traceback = traceback.format_exc()
|
| 49 |
+
logger.error(f"Request failed after {duration:.3f}s:\n{full_traceback}")
|
| 50 |
+
return JSONResponse(
|
| 51 |
+
status_code=500,
|
| 52 |
+
content={"error": "Internal server error", "detail": str(e)}
|
| 53 |
+
)
|
| 54 |
+
|
| 55 |
+
app.add_middleware(LoggingMiddleware)
|
| 56 |
|
| 57 |
|
| 58 |
@app.exception_handler(Exception)
|