diff --git a/newrelic/common/async_wrapper.py b/newrelic/common/async_wrapper.py index 29d7809d5e..a2fd22f02c 100644 --- a/newrelic/common/async_wrapper.py +++ b/newrelic/common/async_wrapper.py @@ -93,7 +93,7 @@ async def wrapper(*args, **kwargs): with trace: while True: try: - g.asend(value).send(None) + yielded = await g.asend(value) except StopAsyncIteration as e: # The underlying async generator has finished, return propagates a new StopAsyncIteration return @@ -107,7 +107,7 @@ async def wrapper(*args, **kwargs): # An exception was thrown with .athrow(), propagate to the original async generator. # Return value logic must be identical to .asend() try: - g.athrow(type(e), e).send(None) + value = yield await g.athrow(type(e), e) except StopAsyncIteration as e: # The underlying async generator has finished, return propagates a new StopAsyncIteration return diff --git a/tests/agent_features/_test_async_generator_trace.py b/tests/agent_features/_test_async_generator_trace.py index 11efef1112..8e7703a0db 100644 --- a/tests/agent_features/_test_async_generator_trace.py +++ b/tests/agent_features/_test_async_generator_trace.py @@ -260,6 +260,37 @@ async def _test(): assert full_metrics[key].total_exclusive_call_time < 0.2 +@validate_transaction_metrics( + "test_asend_receives_a_value", + background_task=True, + scoped_metrics=[("Function/agen", 1)], + rollup_metrics=[("Function/agen", 1)], +) +def test_asend_receives_a_value(event_loop): + _received = [] + @function_trace(name="agen") + async def agen(): + value = yield + _received.append(value) + yield value + + @background_task(name="test_asend_receives_a_value") + async def _test(): + gen = agen() + + # kickstart the coroutine + await anext(gen) + + assert await gen.asend("foobar") == "foobar" + assert _received and _received[0] == "foobar" + + # finish consumption of the coroutine if necessary + async for _ in gen: + pass + + event_loop.run_until_complete(_test()) + + @validate_transaction_metrics( "test_athrow_yields_a_value", background_task=True,