From c8fc77d385ef455728fd288988bd043b3bc30a30 Mon Sep 17 00:00:00 2001 From: Florian Dellekart Date: Wed, 26 Jun 2024 21:57:17 +0200 Subject: [PATCH 1/3] fix(grpc): Return propagate proper metadata object instead of list in client interceptor Fixes #2509 --- sentry_sdk/integrations/grpc/aio/client.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/sentry_sdk/integrations/grpc/aio/client.py b/sentry_sdk/integrations/grpc/aio/client.py index b67481b5b5..5b687ef416 100644 --- a/sentry_sdk/integrations/grpc/aio/client.py +++ b/sentry_sdk/integrations/grpc/aio/client.py @@ -6,6 +6,7 @@ ClientCallDetails, UnaryUnaryCall, UnaryStreamCall, + Metadata, ) from google.protobuf.message import Message @@ -20,20 +21,10 @@ class ClientInterceptor: def _update_client_call_details_metadata_from_scope( client_call_details: ClientCallDetails, ) -> ClientCallDetails: - metadata = ( - list(client_call_details.metadata) if client_call_details.metadata else [] - ) + if client_call_details.metadata is None: + client_call_details = client_call_details._replace(metadata=Metadata()) for key, value in Scope.get_current_scope().iter_trace_propagation_headers(): - metadata.append((key, value)) - - client_call_details = ClientCallDetails( - method=client_call_details.method, - timeout=client_call_details.timeout, - metadata=metadata, - credentials=client_call_details.credentials, - wait_for_ready=client_call_details.wait_for_ready, - ) - + client_call_details.metadata.add(key, value) return client_call_details From ddba2a9803d56eae70a9b6230a39ede4b8c6d920 Mon Sep 17 00:00:00 2001 From: Florian Dellekart Date: Wed, 3 Jul 2024 14:59:00 +0200 Subject: [PATCH 2/3] fix(grpc): Transform metadata into Metadata object in case it's a tuple Up until version 1.65.0 of grpcio, the metadata was not guaranteed to arrive as the type specified in annotations but could be a tuple. To support versions before that we check and transform it here. --- sentry_sdk/integrations/grpc/aio/client.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sentry_sdk/integrations/grpc/aio/client.py b/sentry_sdk/integrations/grpc/aio/client.py index 5b687ef416..6230e311a7 100644 --- a/sentry_sdk/integrations/grpc/aio/client.py +++ b/sentry_sdk/integrations/grpc/aio/client.py @@ -23,6 +23,10 @@ def _update_client_call_details_metadata_from_scope( ) -> ClientCallDetails: if client_call_details.metadata is None: client_call_details = client_call_details._replace(metadata=Metadata()) + elif not isinstance(client_call_details.metadata, Metadata): + client_call_details = client_call_details._replace( + metadata=Metadata.from_tuple(client_call_details.metadata) + ) for key, value in Scope.get_current_scope().iter_trace_propagation_headers(): client_call_details.metadata.add(key, value) return client_call_details From 0323fd790287e8428927074d2b46aaff1cfcf733 Mon Sep 17 00:00:00 2001 From: Daniel Szoke Date: Thu, 5 Dec 2024 12:43:21 +0100 Subject: [PATCH 3/3] docs(grpc): Add comment about workaround --- sentry_sdk/integrations/grpc/aio/client.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sentry_sdk/integrations/grpc/aio/client.py b/sentry_sdk/integrations/grpc/aio/client.py index 6230e311a7..0ab8abb048 100644 --- a/sentry_sdk/integrations/grpc/aio/client.py +++ b/sentry_sdk/integrations/grpc/aio/client.py @@ -24,6 +24,8 @@ def _update_client_call_details_metadata_from_scope( if client_call_details.metadata is None: client_call_details = client_call_details._replace(metadata=Metadata()) elif not isinstance(client_call_details.metadata, Metadata): + # This is a workaround for a GRPC bug, which was fixed in grpcio v1.60.0 + # See https://github.com/grpc/grpc/issues/34298. client_call_details = client_call_details._replace( metadata=Metadata.from_tuple(client_call_details.metadata) )