Skip to content

Commit 405272c

Browse files
parthearosiezougcf-owl-bot[bot]
authoredOct 17, 2023
fix: ensure exception is available when BackgroundConsumer open stream fails (#357)
* fix: ensure exception is available when BackgroundConsumer open stream fails * chore: fix coverage * Address review comments * revert * address review feedback * raise grpc.RpcError instead of GoogleAPICallError * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Rosie Zou <rosiezou@users.noreply.github.com> Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
1 parent 6251eab commit 405272c

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed
 

Diff for: ‎google/api_core/bidi.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,7 @@ def _is_active(self):
9292
# Note: there is a possibility that this starts *before* the call
9393
# property is set. So we have to check if self.call is set before
9494
# seeing if it's active.
95-
if self.call is not None and not self.call.is_active():
96-
return False
97-
else:
98-
return True
95+
return self.call is not None and self.call.is_active()
9996

10097
def __iter__(self):
10198
if self._initial_request is not None:
@@ -265,6 +262,10 @@ def add_done_callback(self, callback):
265262
self._callbacks.append(callback)
266263

267264
def _on_call_done(self, future):
265+
# This occurs when the RPC errors or is successfully terminated.
266+
# Note that grpc's "future" here can also be a grpc.RpcError.
267+
# See note in https://github.com/grpc/grpc/issues/10885#issuecomment-302651331
268+
# that `grpc.RpcError` is also `grpc.call`.
268269
for callback in self._callbacks:
269270
callback(future)
270271

@@ -276,7 +277,13 @@ def open(self):
276277
request_generator = _RequestQueueGenerator(
277278
self._request_queue, initial_request=self._initial_request
278279
)
279-
call = self._start_rpc(iter(request_generator), metadata=self._rpc_metadata)
280+
try:
281+
call = self._start_rpc(iter(request_generator), metadata=self._rpc_metadata)
282+
except exceptions.GoogleAPICallError as exc:
283+
# The original `grpc.RpcError` (which is usually also a `grpc.Call`) is
284+
# available from the ``response`` property on the mapped exception.
285+
self._on_call_done(exc.response)
286+
raise
280287

281288
request_generator.call = call
282289

Diff for: ‎tests/unit/test_bidi.py

+15
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,21 @@ def test_wake_on_error(self):
804804
while consumer.is_active:
805805
pass
806806

807+
def test_rpc_callback_fires_when_consumer_start_fails(self):
808+
expected_exception = exceptions.InvalidArgument(
809+
"test", response=grpc.StatusCode.INVALID_ARGUMENT
810+
)
811+
callback = mock.Mock(spec=["__call__"])
812+
813+
rpc, _ = make_rpc()
814+
bidi_rpc = bidi.BidiRpc(rpc)
815+
bidi_rpc.add_done_callback(callback)
816+
bidi_rpc._start_rpc.side_effect = expected_exception
817+
818+
consumer = bidi.BackgroundConsumer(bidi_rpc, on_response=None)
819+
consumer.start()
820+
assert callback.call_args.args[0] == grpc.StatusCode.INVALID_ARGUMENT
821+
807822
def test_consumer_expected_error(self, caplog):
808823
caplog.set_level(logging.DEBUG)
809824

0 commit comments

Comments
 (0)
Please sign in to comment.