likhonsheikhdev commited on
Commit
2f2ddd9
·
verified ·
1 Parent(s): 7222b60

Add Anthropic-compatible HTTP error handling

Browse files
Files changed (1) hide show
  1. main.py +60 -2
main.py CHANGED
@@ -4,8 +4,9 @@ Full compatibility with Anthropic Messages API + Interleaved Thinking
4
  Supports: /v1/messages, /anthropic/v1/messages, /api/v1/messages
5
  Optimized for: 2 vCPU, 16GB RAM
6
  """
7
- from fastapi import FastAPI, HTTPException, Header, Request
8
- from fastapi.responses import StreamingResponse, HTMLResponse, FileResponse
 
9
  from fastapi.staticfiles import StaticFiles
10
  from fastapi.middleware.cors import CORSMiddleware
11
  from pydantic import BaseModel, Field
@@ -68,6 +69,63 @@ app.add_middleware(
68
  )
69
 
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  # ============== Anthropic API Models ==============
72
 
73
  class TextBlock(BaseModel):
 
4
  Supports: /v1/messages, /anthropic/v1/messages, /api/v1/messages
5
  Optimized for: 2 vCPU, 16GB RAM
6
  """
7
+ from fastapi import FastAPI, HTTPException, Header, Request, status
8
+ from fastapi.responses import StreamingResponse, HTMLResponse, FileResponse, JSONResponse
9
+ from fastapi.exceptions import RequestValidationError
10
  from fastapi.staticfiles import StaticFiles
11
  from fastapi.middleware.cors import CORSMiddleware
12
  from pydantic import BaseModel, Field
 
69
  )
70
 
71
 
72
+ # ============== Anthropic Error Handling ==============
73
+
74
+ class AnthropicError(BaseModel):
75
+ type: str
76
+ message: str
77
+
78
+
79
+ class AnthropicErrorResponse(BaseModel):
80
+ type: str = "error"
81
+ error: AnthropicError
82
+
83
+
84
+ def create_error_response(status_code: int, error_type: str, message: str) -> JSONResponse:
85
+ """Create Anthropic-compatible error response."""
86
+ return JSONResponse(
87
+ status_code=status_code,
88
+ content={
89
+ "type": "error",
90
+ "error": {
91
+ "type": error_type,
92
+ "message": message
93
+ }
94
+ }
95
+ )
96
+
97
+
98
+ @app.exception_handler(RequestValidationError)
99
+ async def validation_exception_handler(request: Request, exc: RequestValidationError):
100
+ """Handle validation errors (400 - invalid_request_error)."""
101
+ errors = exc.errors()
102
+ message = "; ".join([f"{e['loc'][-1]}: {e['msg']}" for e in errors])
103
+ return create_error_response(400, "invalid_request_error", message)
104
+
105
+
106
+ @app.exception_handler(HTTPException)
107
+ async def http_exception_handler(request: Request, exc: HTTPException):
108
+ """Handle HTTP exceptions with Anthropic error format."""
109
+ error_mapping = {
110
+ 400: "invalid_request_error",
111
+ 401: "authentication_error",
112
+ 403: "permission_error",
113
+ 404: "not_found_error",
114
+ 413: "request_too_large",
115
+ 429: "rate_limit_error",
116
+ 500: "api_error",
117
+ 529: "overloaded_error"
118
+ }
119
+ error_type = error_mapping.get(exc.status_code, "api_error")
120
+ return create_error_response(exc.status_code, error_type, str(exc.detail))
121
+
122
+
123
+ @app.exception_handler(Exception)
124
+ async def general_exception_handler(request: Request, exc: Exception):
125
+ """Handle unexpected errors (500 - api_error)."""
126
+ return create_error_response(500, "api_error", f"An unexpected error occurred: {str(exc)}")
127
+
128
+
129
  # ============== Anthropic API Models ==============
130
 
131
  class TextBlock(BaseModel):