diff --git a/src/ruby/lib/grpc/generic/active_call.rb b/src/ruby/lib/grpc/generic/active_call.rb index 87b29c26eaed6301e63fa33d6eb79946fa102521..10eb70b4a7f6147b0acf3c46a624e07c7987833b 100644 --- a/src/ruby/lib/grpc/generic/active_call.rb +++ b/src/ruby/lib/grpc/generic/active_call.rb @@ -480,7 +480,20 @@ module GRPC def bidi_streamer(requests, metadata: {}, &blk) raise_error_if_already_executed # Metadata might have already been sent if this is an operation view - merge_metadata_and_send_if_not_already_sent(metadata) + begin + merge_metadata_and_send_if_not_already_sent(metadata) + rescue GRPC::Core::CallError => e + batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil) + set_input_stream_done + set_output_stream_done + attach_status_results_and_complete_call(batch_result) + raise e + rescue => e + set_input_stream_done + set_output_stream_done + raise e + end + bd = BidiCall.new(@call, @marshal, @unmarshal, diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb index 42cff4041bbbee9b97ef4900f42cde5c3caaeadf..e1e7a535fb621b9f0d758b886cda61a11d84252a 100644 --- a/src/ruby/spec/generic/client_stub_spec.rb +++ b/src/ruby/spec/generic/client_stub_spec.rb @@ -616,8 +616,22 @@ describe 'ClientStub' do th.join end - # TODO: add test for metadata-related ArgumentError in a bidi call once - # issue mentioned in https://github.com/grpc/grpc/issues/10526 is fixed + it 'should raise ArgumentError if metadata contains invalid values' do + @metadata.merge!(k3: 3) + stub = GRPC::ClientStub.new(@host, :this_channel_is_insecure) + expect do + get_responses(stub).collect { |r| r } + end.to raise_error(ArgumentError, + /Header values must be of type string or array/) + end + + it 'terminates if the call fails to start' do + # don't start the server + stub = GRPC::ClientStub.new(@host, :this_channel_is_insecure) + expect do + get_responses(stub, deadline: from_relative_time(0)).collect { |r| r } + end.to raise_error(GRPC::BadStatus) + end it 'should send metadata to the server ok' do th = run_bidi_streamer_echo_ping_pong(@sent_msgs, @pass, true, @@ -630,9 +644,9 @@ describe 'ClientStub' do end describe 'without a call operation' do - def get_responses(stub) + def get_responses(stub, deadline: nil) e = stub.bidi_streamer(@method, @sent_msgs, noop, noop, - metadata: @metadata) + metadata: @metadata, deadline: deadline) expect(e).to be_a(Enumerator) e end @@ -644,10 +658,10 @@ describe 'ClientStub' do after(:each) do @op.wait # make sure wait doesn't hang end - def get_responses(stub, run_start_call_first: false) + def get_responses(stub, run_start_call_first: false, deadline: nil) @op = stub.bidi_streamer(@method, @sent_msgs, noop, noop, return_op: true, - metadata: @metadata) + metadata: @metadata, deadline: deadline) expect(@op).to be_a(GRPC::ActiveCall::Operation) @op.start_call if run_start_call_first e = @op.execute