Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gRPC (AIO) missing None check for when RPC method not implemented #3108

Closed
ordinary-jamie opened this issue May 29, 2024 · 2 comments
Closed
Assignees

Comments

@ordinary-jamie
Copy link
Contributor

How do you use Sentry?

Sentry Saas (sentry.io)

Version

master

Steps to Reproduce

Call an unimplemented RPC for an gRPC.AIO server using Sentry SDK

Reproducer:

  1. pip install sentry-sdk grpcio grpcio-tools
  2. Get sample Protobuf stubs (grpc/grpc HelloWorld)
# Get a sample protobuf, helloworld proto
curl https://raw.githubusercontent.com/grpc/grpc/v1.62.0/examples/protos/helloworld.proto > helloworld.proto

# Generate stubs
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. --pyi_out=. *.proto

Run test script:

"""Missing None check replication for gRPC AIO."""

import asyncio
import contextlib
import logging

import grpc.aio as grpc
import helloworld_pb2
import helloworld_pb2_grpc
import sentry_sdk
from sentry_sdk.integrations.grpc import GRPCIntegration


@contextlib.asynccontextmanager
async def test_server(port: int = 50051):
    server = grpc.server()
    server.add_insecure_port(f"[::]:{port}")

    try:
        await server.start()
        yield
    finally:
        await server.stop(grace=None)


async def client(port: int = 50051):
    async with grpc.insecure_channel(f"[::]:{port}") as channel:
        stub = helloworld_pb2_grpc.GreeterStub(channel)
        try:
            return await stub.SayHello(helloworld_pb2.HelloRequest(name="Jamie"))
        except grpc.AioRpcError as exc:
            print(exc.details())


async def test():
    port = 50051

    async with test_server(port=port):
        await client(port=port)


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    sentry_sdk.init(integrations=[GRPCIntegration()])
    asyncio.run(test())

Expected Result

Expected RPC error "Method not found!"

Note, grpc.aio.ServerInterceptors should return None if they have not serviced the RPC:

https://grpc.github.io/grpc/python/grpc_asyncio.html#grpc.aio.ServerInterceptor

Returns: An RpcMethodHandler with which the RPC may be serviced if the interceptor chooses to service this RPC, or None otherwise.

Actual Result

ERROR:grpc._cython.cygrpc:Unexpected [AttributeError] raised by servicer method [/helloworld.Greeter/SayHello]
Traceback (most recent call last):
  File "src/python/grpcio/grpc/_cython/_cygrpc/aio/server.pyx.pxi", line 689, in grpc._cython.cygrpc._handle_exceptions
  File "src/python/grpcio/grpc/_cython/_cygrpc/aio/server.pyx.pxi", line 789, in _handle_rpc
  File "src/python/grpcio/grpc/_cython/_cygrpc/aio/server.pyx.pxi", line 383, in _find_method_handler
  File "src/python/grpcio/grpc/_cython/_cygrpc/aio/server.pyx.pxi", line 360, in _run_interceptor
  File ".direnv/python-3.12/lib/python3.12/site-packages/sentry_sdk/integrations/grpc/aio/server.py", line 33, in intercept_service
    if not handler.request_streaming and not handler.response_streaming:
           ^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'request_streaming'
Unexpected <class 'AttributeError'>: 'NoneType' object has no attribute 'request_streaming'
@ordinary-jamie
Copy link
Contributor Author

Hi Sentry team! I created a PR to help communicate the issue better -- happy for you to create your own if that's easier / let me know if you'd like me to fix anything up.

@sentrivana
Copy link
Contributor

Closed via #3109

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

No branches or pull requests

4 participants