Skip to content

Conversation

@timothy-jeong
Copy link

@timothy-jeong timothy-jeong commented Oct 11, 2025

  • Add google.genai.errors. APIError handling at GoogleModel
  • Add test case tests/models/test_googe.py: test_model_status_error

Resolves: #3088

- 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
@timothy-jeong timothy-jeong force-pushed the add-googlemodel-google-specific-error-handling branch from 7ef0b9b to ae45a9b Compare October 11, 2025 08:58
Comment on lines 430 to 439
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
Copy link
Member

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.

Copy link
Author

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.

Copy link
Author

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.

@Kludex Kludex self-assigned this Oct 11, 2025
@timothy-jeong timothy-jeong force-pushed the add-googlemodel-google-specific-error-handling branch from 9eabd64 to 09e053f Compare October 11, 2025 12:05
),
],
)
async def test_model_status_error(
Copy link
Author

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'}"
    )

@timothy-jeong timothy-jeong requested a review from Kludex October 14, 2025 14:29
- Align with other model implementations (openai, groq) by removing unnecessary error transformation logic

Resolves: pydantic#3088
@timothy-jeong timothy-jeong force-pushed the add-googlemodel-google-specific-error-handling branch from 09e053f to eecaa4a Compare October 17, 2025 06:51
@Kludex
Copy link
Member

Kludex commented Oct 17, 2025

For testing, I think for http exceptions, mocking an HTTP response would be okay. Otherwise, you can't consistently reproduce this.

Copy link

@cursor cursor bot left a 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:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Unhandled Exception in Error Handling

The try...except block can raise a TypeError if e.code is None for an APIError. The comparison (status_code := e.code) >= 400 attempts to compare None with an integer, causing an unhandled exception when an APIError lacks a status code.

Fix in Cursor Fix in Web

@timothy-jeong
Copy link
Author

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?

@Kludex
Copy link
Member

Kludex commented Oct 23, 2025

Should I add the test code back?

Yes, that's what I meant with my last comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unified Exception Handling for Various LLM Models

2 participants