diff --git a/sentry_sdk/integrations/grpc/__init__.py b/sentry_sdk/integrations/grpc/__init__.py index d9dcdddb55..4e15f95ae5 100644 --- a/sentry_sdk/integrations/grpc/__init__.py +++ b/sentry_sdk/integrations/grpc/__init__.py @@ -6,6 +6,7 @@ from grpc.aio import Server as AsyncServer from sentry_sdk.integrations import Integration +from sentry_sdk.utils import parse_version from .client import ClientInterceptor from .server import ServerInterceptor @@ -41,6 +42,8 @@ def __getitem__(self, _): P = ParamSpec("P") +GRPC_VERSION = parse_version(grpc.__version__) + def _wrap_channel_sync(func: Callable[P, Channel]) -> Callable[P, Channel]: "Wrapper for synchronous secure and insecure channel." @@ -127,7 +130,21 @@ def patched_aio_server( # type: ignore **kwargs: P.kwargs, ) -> Server: server_interceptor = AsyncServerInterceptor() - interceptors = (server_interceptor, *(interceptors or [])) + interceptors = [ + server_interceptor, + *(interceptors or []), + ] # type: Sequence[grpc.ServerInterceptor] + + try: + # We prefer interceptors as a list because of compatibility with + # opentelemetry https://github.com/getsentry/sentry-python/issues/4389 + # However, prior to grpc 1.42.0, only tuples were accepted, so we + # have no choice there. + if GRPC_VERSION is not None and GRPC_VERSION < (1, 42, 0): + interceptors = tuple(interceptors) + except Exception: + pass + return func(*args, interceptors=interceptors, **kwargs) # type: ignore return patched_aio_server # type: ignore