fix(pydantic-ai): Use first-class hooks when available #5947
2 issues
code-review: Found 2 issues (2 medium)
Medium
Span may leak if update_ai_client_span raises an exception - `sentry_sdk/integrations/pydantic_ai/__init__.py:71-72`
In the on_response hook, update_ai_client_span(span, response) is called on line 71 before span.__exit__(None, None, None) on line 72. If update_ai_client_span raises an exception (e.g., due to malformed response data or an internal error in _set_usage_data), the span that was opened via span.__enter__() in on_request will never be closed. This could lead to span leaks and incorrect tracing data. The on_error handler correctly wraps its span.__exit__ call in capture_internal_exceptions(), but on_response doesn't follow this defensive pattern.
Falsy check on metadata overwrites empty dictionaries - `sentry_sdk/integrations/pydantic_ai/patches/agent_run.py:115-116`
The condition if not metadata: on lines 115 and 164 treats empty dictionaries {} as falsy and overwrites them. This is inconsistent with the patched_init in __init__.py which uses if metadata is None. If a user explicitly passes metadata={}, it will be unexpectedly replaced with {"_sentry_span": None}, potentially losing the shared reference intended by patched_init.
Also found at:
sentry_sdk/integrations/pydantic_ai/patches/agent_run.py:164-165
Duration: 5m 6s · Tokens: 1.0M in / 15.1k out · Cost: $1.65 (+extraction: $0.01, +merge: $0.00, +fix_gate: $0.01)
Annotations
Check warning on line 72 in sentry_sdk/integrations/pydantic_ai/__init__.py
sentry-warden / warden: code-review
Span may leak if update_ai_client_span raises an exception
In the `on_response` hook, `update_ai_client_span(span, response)` is called on line 71 before `span.__exit__(None, None, None)` on line 72. If `update_ai_client_span` raises an exception (e.g., due to malformed response data or an internal error in `_set_usage_data`), the span that was opened via `span.__enter__()` in `on_request` will never be closed. This could lead to span leaks and incorrect tracing data. The `on_error` handler correctly wraps its `span.__exit__` call in `capture_internal_exceptions()`, but `on_response` doesn't follow this defensive pattern.
Check warning on line 116 in sentry_sdk/integrations/pydantic_ai/patches/agent_run.py
sentry-warden / warden: code-review
Falsy check on metadata overwrites empty dictionaries
The condition `if not metadata:` on lines 115 and 164 treats empty dictionaries `{}` as falsy and overwrites them. This is inconsistent with the `patched_init` in `__init__.py` which uses `if metadata is None`. If a user explicitly passes `metadata={}`, it will be unexpectedly replaced with `{"_sentry_span": None}`, potentially losing the shared reference intended by `patched_init`.
Check warning on line 165 in sentry_sdk/integrations/pydantic_ai/patches/agent_run.py
sentry-warden / warden: code-review
[BRN-UJC] Falsy check on metadata overwrites empty dictionaries (additional location)
The condition `if not metadata:` on lines 115 and 164 treats empty dictionaries `{}` as falsy and overwrites them. This is inconsistent with the `patched_init` in `__init__.py` which uses `if metadata is None`. If a user explicitly passes `metadata={}`, it will be unexpectedly replaced with `{"_sentry_span": None}`, potentially losing the shared reference intended by `patched_init`.