-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Wrap GoogleModel google.genai.errors.APIError in ModelHTTPError so it works with FallbackModel
#3139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrap GoogleModel google.genai.errors.APIError in ModelHTTPError so it works with FallbackModel
#3139
Conversation
7ef0b9b to
ae45a9b
Compare
| try: | ||
| return await func(model=self._model_name, contents=contents, config=config) # type: ignore | ||
| except ( | ||
| errors.APIError, | ||
| errors.UnknownFunctionCallArgumentError, | ||
| errors.UnsupportedFunctionError, | ||
| errors.FunctionInvocationError, | ||
| errors.UnknownApiResponseError, | ||
| ) as e: | ||
| raise self._handle_google_error(e) from e |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can do what we do in the other models, and just have a single except.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I initially believed I needed to explicitly handle all of the more specific exceptions defined in google.genai.errors (e.g., UnknownFunctionCallArgumentError, UnknownApiResponseError) to provide more detailed error messages.
However, after reviewing the implementation for other models (like Groq and OpenAI, which only handle their respective APIStatusError subclasses to catch HTTP status codes ≥400), I realize I can simplify the approach.
I'll only focus on the main google.genai.errors.APIError to align with the standard pattern for re-raising a ModelHTTPError.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Kludex ~
thank you for your review
I've changed the code to only return a ModelHttpError for errors that have an explicit Status Code, similar to how other models handle it.
9eabd64 to
09e053f
Compare
tests/models/test_google.py
Outdated
| ), | ||
| ], | ||
| ) | ||
| async def test_model_status_error( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should I make MockGoogle and inject mock client like groq test code do?
def test_model_status_error(allow_model_requests: None) -> None:
mock_client = MockGroq.create_mock(
APIStatusError(
'test error',
response=httpx.Response(status_code=500, request=httpx.Request('POST', 'https://example.com/v1')),
body={'error': 'test error'},
)
)
m = GroqModel('llama-3.3-70b-versatile', provider=GroqProvider(groq_client=mock_client))
agent = Agent(m)
with pytest.raises(ModelHTTPError) as exc_info:
agent.run_sync('hello')
assert str(exc_info.value) == snapshot(
"status_code: 500, model_name: llama-3.3-70b-versatile, body: {'error': 'test error'}"
)09e053f to
eecaa4a
Compare
|
For testing, I think for http exceptions, mocking an HTTP response would be okay. Otherwise, you can't consistently reproduce this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is being reviewed by Cursor Bugbot
Details
You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
| try: | ||
| return await func(model=self._model_name, contents=contents, config=config) # type: ignore | ||
| except errors.APIError as e: | ||
| if (status_code := e.code) >= 400: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
Hi @Kludex I identified that the test code was causing the CI failures, so I removed it entirely. Now, it seems the coverage test is failing as a result. Should I add the test code back? |
Yes, that's what I meant with my last comment. |
|
@timothy-jeong Can you please add a test to this PR so we can get it merged? |
|
@DouweM |
- Add error handling helper method `_handle_google_error` - Convert Google API errors to ModelHTTPError with proper status codes - Map specific function-related errors (400-level) appropriately - Keep original error details in response body - Add test cases for API error handling Resolves: pydantic#3088
- Align with other model implementations (openai, groq) by removing unnecessary error transformation logic Resolves: pydantic#3088
Head branch was pushed to by a user without write access
4125049 to
7362aea
Compare
| return await func(model=self._model_name, contents=contents, config=config) # type: ignore | ||
| except errors.APIError as e: | ||
| if (status_code := e.code) >= 400: | ||
| raise ModelHTTPError(status_code=status_code, model_name=self._model_name, body=e.details) from e # pyright: ignore[reportUnknownArgumentType, reportUnknownMemberType] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
finally pass all required tests, for lint I add this ignore comment
fa53738 to
35787d4
Compare
|
Thank you so much for your patience over the last month. I apologize for the significant delay due to being extremely busy. I have now pushed an update with the following changes:
Please let me know if there's anything else I need to address. |
GoogleModel google.genai.errors.APIError in ModelHTTPError so it works with FallbackModel
google.genai.errors. APIErrorhandling atGoogleModeltests/models/test_googe.py: test_model_status_errorResolves: #3088
Note
Catches google.genai APIError in
GoogleModel._generate_contentand raisesModelHTTPErrorwith status code and details.pydantic_ai_slim/pydantic_ai/models/google.py):generate_content/generate_content_streamcall to catchgoogle.genai.errors.APIError; rethrow asModelHTTPError(>=400) with status and details.ModelHTTPErrorandgoogle.genai.errors.Written by Cursor Bugbot for commit 653aca1. This will update automatically on new commits. Configure here.