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>

Files changed (1) hide show
  1. app.py +25 -15
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
- @app.middleware("http")
32
- async def log_requests(request: Request, call_next):
33
- """Log all incoming requests and responses."""
34
- start_time = datetime.utcnow()
35
- logger.info(f"Request: {request.method} {request.url.path}")
36
-
37
- try:
38
- response = await call_next(request)
39
- duration = (datetime.utcnow() - start_time).total_seconds()
40
- logger.info(f"Response: {response.status_code} - {duration:.3f}s")
41
- return response
42
- except Exception as e:
43
- duration = (datetime.utcnow() - start_time).total_seconds()
44
- logger.error(f"Request failed after {duration:.3f}s: {str(e)}")
45
- raise
 
 
 
 
 
 
 
 
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)