Skip to content

Commit 5a36f52

Browse files
committed
refactor(gapic): document graceful bypass of otel errors and remove pragma
Document intentional bypass of OpenTelemetry exceptions during span context creation to guarantee RPC success. - Adds explanatory comment for why Exception is caught and degraded to nullcontext. - Removes '# pragma: NO COVER'. - Adds test_wrap_method_otel_tracing_start_span_error_bypasses_tracing to verify fallback behavior and maintain 100% statement and branch coverage.
1 parent 6a1eeb0 commit 5a36f52

2 files changed

Lines changed: 40 additions & 1 deletion

File tree

packages/google-api-core/google/api_core/gapic_v1/method.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,8 @@ def __call__(
267267
kind=trace.SpanKind.CLIENT,
268268
attributes=self._span_attributes,
269269
)
270-
except Exception: # pragma: NO COVER
270+
except Exception:
271+
# Purposefully and gracefully bypass OpenTelemetry errors to ensure RPC success.
271272
span_context_manager = contextlib.nullcontext()
272273

273274
with span_context_manager as span:

packages/google-api-core/tests/unit/gapic/test_method.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,44 @@ def test_wrap_method_otel_tracing_provider_type_error(monkeypatch):
684684
mock_target.assert_called_once()
685685

686686

687+
def test_wrap_method_otel_tracing_start_span_error_bypasses_tracing(monkeypatch):
688+
"""Proves that if start_as_current_span raises an Exception, execution proceeds gracefully with nullcontext."""
689+
monkeypatch.setenv("GOOGLE_SDK_EXPERIMENTAL_PYTHON_TRACING_ENABLED", "true")
690+
mock_target = mock.Mock(return_value="success")
691+
692+
mock_tracer = mock.MagicMock()
693+
mock_tracer.start_as_current_span.side_effect = RuntimeError(
694+
"Tracing context failed"
695+
)
696+
697+
mock_trace = mock.Mock()
698+
mock_trace.get_tracer.return_value = mock_tracer
699+
mock_trace.SpanKind.CLIENT = "CLIENT"
700+
701+
with (
702+
mock.patch(
703+
"google.api_core._observability.is_otel_capabilities_enabled",
704+
return_value=True,
705+
),
706+
mock.patch.dict(
707+
sys.modules,
708+
{
709+
"opentelemetry": mock.Mock(trace=mock_trace),
710+
"opentelemetry.trace": mock_trace,
711+
},
712+
),
713+
):
714+
wrapped = google.api_core.gapic_v1.method.wrap_method(
715+
mock_target,
716+
method_name="google.cloud.secretmanager.v1.SecretManagerService/ListSecrets",
717+
)
718+
result = wrapped()
719+
720+
assert result == "success"
721+
mock_target.assert_called_once()
722+
mock_tracer.start_as_current_span.assert_called_once()
723+
724+
687725
def test_wrap_method_async_otel_tracing(monkeypatch):
688726
"""Proves that method_async.wrap_method correctly passes client_options and method_name to _GapicCallable."""
689727
from google.api_core.gapic_v1 import method_async

0 commit comments

Comments
 (0)