Claude Code Claude Opus 4.6 commited on
Commit
cc6e5c7
·
1 Parent(s): d173fe5

Claude Code: Add robust error handling with stderr logging

Browse files

- Wrap main execution loop in try-except with full traceback
- Log all startup/debug output to stderr (not buffered stdout)
- Add KeyboardInterrupt handling for graceful shutdown
- Update entrypoint.sh to explicitly flush stderr

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Files changed (2) hide show
  1. app.py +18 -5
  2. entrypoint.sh +3 -3
app.py CHANGED
@@ -24,11 +24,11 @@ def get_app():
24
 
25
  print(">>> CAIN: Creating FastAPI app...", flush=True)
26
 
27
- # Configure stdout logging
28
  logging.basicConfig(
29
  level=logging.INFO,
30
  format='%(asctime)s - %(levelname)s - %(message)s',
31
- handlers=[logging.StreamHandler(sys.stdout)]
32
  )
33
  logger = logging.getLogger(__name__)
34
  logger.info(">>> CAIN: FastAPI initialization starting")
@@ -83,6 +83,19 @@ except Exception as e:
83
 
84
  if __name__ == "__main__":
85
  import uvicorn
86
- port = int(os.environ.get('PORT', 7860))
87
- print(f">>> CAIN: Starting uvicorn on port {port}...", flush=True)
88
- uvicorn.run(app, host="0.0.0.0", port=port)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
  print(">>> CAIN: Creating FastAPI app...", flush=True)
26
 
27
+ # Configure stderr logging for real-time debugging (stdout can be buffered)
28
  logging.basicConfig(
29
  level=logging.INFO,
30
  format='%(asctime)s - %(levelname)s - %(message)s',
31
+ handlers=[logging.StreamHandler(sys.stderr)]
32
  )
33
  logger = logging.getLogger(__name__)
34
  logger.info(">>> CAIN: FastAPI initialization starting")
 
83
 
84
  if __name__ == "__main__":
85
  import uvicorn
86
+
87
+ # Wrap main execution in try-except for graceful error handling
88
+ try:
89
+ port = int(os.environ.get('PORT', 7860))
90
+ print(f">>> CAIN: Starting uvicorn on port {port}...", flush=True, file=sys.stderr)
91
+ uvicorn.run(app, host="0.0.0.0", port=port)
92
+ except Exception as e:
93
+ # Log full stack trace to stderr before exiting
94
+ print(f">>> CAIN: FATAL - Main process crashed!", flush=True, file=sys.stderr)
95
+ print(f">>> CAIN: Error: {type(e).__name__}: {e}", flush=True, file=sys.stderr)
96
+ print(f">>> CAIN: Full traceback:", flush=True, file=sys.stderr)
97
+ traceback.print_exc(file=sys.stderr)
98
+ sys.exit(1)
99
+ except KeyboardInterrupt:
100
+ print("\n>>> CAIN: Interrupted by user", flush=True, file=sys.stderr)
101
+ sys.exit(0)
entrypoint.sh CHANGED
@@ -41,9 +41,9 @@ echo "=========================================="
41
 
42
  # Auto-restart loop: if uvicorn crashes, wait 2s and restart
43
  while true; do
44
- echo "[$(date -u +"%Y-%m-%dT%H:%M:%SZ")] Starting uvicorn on 0.0.0.0:${PORT:-7860}..."
45
- uvicorn app:app --host 0.0.0.0 --port "${PORT:-7860}" 2>&1
46
- EXIT_CODE=$?
47
 
48
  echo "[$(date -u +"%Y-%m-%dT%H:%M:%SZ")] uvicorn exited with code: $EXIT_CODE"
49
 
 
41
 
42
  # Auto-restart loop: if uvicorn crashes, wait 2s and restart
43
  while true; do
44
+ echo "[$(date -u +"%Y-%m-%dT%H:%M:%SZ")] Starting uvicorn on 0.0.0.0:${PORT:-7860}..." >&2
45
+ uvicorn app:app --host 0.0.0.0 --port "${PORT:-7860}" 2>&1 | tee >(cat >&2)
46
+ EXIT_CODE=${PIPESTATUS[0]}
47
 
48
  echo "[$(date -u +"%Y-%m-%dT%H:%M:%SZ")] uvicorn exited with code: $EXIT_CODE"
49