Skip to content
This repository was archived by the owner on Jun 5, 2025. It is now read-only.

Commit 6d619f2

Browse files
authored
Merge pull request #421 from stacklok/issue-201-v1
fix: wrap provider error codes into HTTP Exceptions
2 parents a8f8a78 + 3c35bb5 commit 6d619f2

File tree

6 files changed

+88
-11
lines changed

6 files changed

+88
-11
lines changed

src/codegate/llm_utils/llmclient.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,4 @@ async def _complete_litellm(
149149

150150
except Exception as e:
151151
logger.error(f"LiteLLM completion failed {model} ({content}): {e}")
152-
return {}
152+
raise e

src/codegate/providers/anthropic/provider.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import structlog
23
from typing import Optional
34

45
from fastapi import Header, HTTPException, Request
@@ -53,5 +54,16 @@ async def create_message(
5354
data = json.loads(body)
5455

5556
is_fim_request = self._is_fim_request(request, data)
56-
stream = await self.complete(data, x_api_key, is_fim_request)
57+
try:
58+
stream = await self.complete(data, x_api_key, is_fim_request)
59+
except Exception as e:
60+
#  check if we have an status code there
61+
if hasattr(e, "status_code"):
62+
# log the exception
63+
logger = structlog.get_logger("codegate")
64+
logger.error("Error in AnthropicProvider completion", error=str(e))
65+
raise HTTPException(status_code=e.status_code, detail=str(e)) # type: ignore
66+
else:
67+
# just continue raising the exception
68+
raise e
5769
return self._completion_handler.create_response(stream)

src/codegate/providers/llamacpp/provider.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import json
2+
import structlog
23
from typing import Optional
34

4-
from fastapi import Request
5+
from fastapi import Request, HTTPException
56

67
from codegate.pipeline.base import SequentialPipelineProcessor
78
from codegate.pipeline.output import OutputPipelineProcessor
@@ -10,7 +11,7 @@
1011
from codegate.providers.llamacpp.normalizer import LLamaCppInputNormalizer, LLamaCppOutputNormalizer
1112

1213

13-
class LlamaCppProvider(BaseProvider):
14+
class LlamaCppProvider(BaseProvider):
1415
def __init__(
1516
self,
1617
pipeline_processor: Optional[SequentialPipelineProcessor] = None,
@@ -46,7 +47,24 @@ async def create_completion(
4647
):
4748
body = await request.body()
4849
data = json.loads(body)
50+
logger = structlog.get_logger("codegate")
4951

5052
is_fim_request = self._is_fim_request(request, data)
51-
stream = await self.complete(data, None, is_fim_request=is_fim_request)
53+
try:
54+
stream = await self.complete(data, None, is_fim_request=is_fim_request)
55+
except RuntimeError as e:
56+
# propagate as error 500
57+
logger.error("Error in LlamaCppProvider completion", error=str(e))
58+
raise HTTPException(status_code=500, detail=str(e))
59+
except ValueError as e:
60+
# capture well known exceptions
61+
logger.error("Error in LlamaCppProvider completion", error=str(e))
62+
if str(e).startswith("Model path does not exist") or \
63+
str(e).startswith("No file found"):
64+
raise HTTPException(status_code=404, detail=str(e))
65+
elif "exceed" in str(e):
66+
raise HTTPException(status_code=429, detail=str(e))
67+
else:
68+
# just continue raising the exception
69+
raise e
5270
return self._completion_handler.create_response(stream)

src/codegate/providers/ollama/provider.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import json
22
from typing import Optional
33

4-
from fastapi import Request
4+
from fastapi import Request, HTTPException
5+
import httpx
6+
import structlog
57

68
from codegate.config import Config
79
from codegate.pipeline.base import SequentialPipelineProcessor
@@ -58,5 +60,20 @@ async def create_completion(request: Request):
5860
data["base_url"] = self.base_url
5961

6062
is_fim_request = self._is_fim_request(request, data)
61-
stream = await self.complete(data, api_key=None, is_fim_request=is_fim_request)
63+
try:
64+
stream = await self.complete(data, api_key=None, is_fim_request=is_fim_request)
65+
except httpx.ConnectError as e:
66+
logger = structlog.get_logger("codegate")
67+
logger.error("Error in OllamaProvider completion", error=str(e))
68+
raise HTTPException(status_code=503, detail="Ollama service is unavailable")
69+
except Exception as e:
70+
#  check if we have an status code there
71+
if hasattr(e, "status_code"):
72+
# log the exception
73+
logger = structlog.get_logger("codegate")
74+
logger.error("Error in OllamaProvider completion", error=str(e))
75+
raise HTTPException(status_code=e.status_code, detail=str(e)) # type: ignore
76+
else:
77+
# just continue raising the exception
78+
raise e
6279
return self._completion_handler.create_response(stream)

src/codegate/providers/openai/provider.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import structlog
23
from typing import Optional
34

45
from fastapi import Header, HTTPException, Request
@@ -54,5 +55,16 @@ async def create_completion(
5455
data = json.loads(body)
5556

5657
is_fim_request = self._is_fim_request(request, data)
57-
stream = await self.complete(data, api_key, is_fim_request=is_fim_request)
58+
try:
59+
stream = await self.complete(data, api_key, is_fim_request=is_fim_request)
60+
except Exception as e:
61+
#  check if we have an status code there
62+
if hasattr(e, "status_code"):
63+
logger = structlog.get_logger("codegate")
64+
logger.error("Error in OpenAIProvider completion", error=str(e))
65+
66+
raise HTTPException(status_code=e.status_code, detail=str(e)) # type: ignore
67+
else:
68+
# just continue raising the exception
69+
raise e
5870
return self._completion_handler.create_response(stream)

src/codegate/providers/vllm/provider.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import structlog
23
from typing import Optional
34

45
import httpx
@@ -52,7 +53,10 @@ async def get_models(authorization: str = Header(..., description="Bearer token"
5253

5354
token = authorization.split(" ")[1]
5455
config = Config.get_config()
55-
base_url = config.provider_urls.get("vllm")
56+
if config:
57+
base_url = config.provider_urls.get("vllm")
58+
else:
59+
base_url = ""
5660

5761
async with httpx.AsyncClient() as client:
5862
response = await client.get(
@@ -76,8 +80,22 @@ async def create_completion(
7680

7781
# Add the vLLM base URL to the request
7882
config = Config.get_config()
79-
data["base_url"] = config.provider_urls.get("vllm")
83+
if config:
84+
data["base_url"] = config.provider_urls.get("vllm")
85+
else:
86+
data["base_url"] = ""
8087

8188
is_fim_request = self._is_fim_request(request, data)
82-
stream = await self.complete(data, api_key, is_fim_request=is_fim_request)
89+
try:
90+
stream = await self.complete(data, api_key, is_fim_request=is_fim_request)
91+
except Exception as e:
92+
#  check if we have an status code there
93+
if hasattr(e, "status_code"):
94+
logger = structlog.get_logger("codegate")
95+
logger.error("Error in VLLMProvider completion", error=str(e))
96+
97+
raise HTTPException(status_code=e.status_code, detail=str(e)) # type: ignore
98+
else:
99+
# just continue raising the exception
100+
raise e
83101
return self._completion_handler.create_response(stream)

0 commit comments

Comments
 (0)