diff --git a/react_on_rails_pro/lib/react_on_rails_pro/stream_request.rb b/react_on_rails_pro/lib/react_on_rails_pro/stream_request.rb index 4090958a0f..5be2cb5776 100644 --- a/react_on_rails_pro/lib/react_on_rails_pro/stream_request.rb +++ b/react_on_rails_pro/lib/react_on_rails_pro/stream_request.rb @@ -113,7 +113,7 @@ def each_chunk(&block) def process_response_chunks(stream_response, error_body) loop_response_lines(stream_response) do |chunk| - if stream_response.is_a?(HTTPX::ErrorResponse) || stream_response.status >= 400 + if response_has_error_status?(stream_response) error_body << chunk next end @@ -123,6 +123,15 @@ def process_response_chunks(stream_response, error_body) end end + def response_has_error_status?(response) + return true if response.is_a?(HTTPX::ErrorResponse) + + response.status >= 400 + rescue NoMethodError + # HTTPX::StreamResponse can fail to delegate #status for non-streaming errors. + true + end + def handle_http_error(error, error_body, send_bundle) response = error.response case response.status diff --git a/react_on_rails_pro/spec/react_on_rails_pro/stream_request_spec.rb b/react_on_rails_pro/spec/react_on_rails_pro/stream_request_spec.rb index c8a12e5b0c..7b5d9a41ec 100644 --- a/react_on_rails_pro/spec/react_on_rails_pro/stream_request_spec.rb +++ b/react_on_rails_pro/spec/react_on_rails_pro/stream_request_spec.rb @@ -10,4 +10,32 @@ expect(result).to be_a(ReactOnRailsPro::StreamDecorator) end end + + describe "#process_response_chunks" do + subject(:request) { described_class.send(:new) { nil } } + + let(:error_body) { +"" } + + it "treats responses without status delegation as error responses" do + response = Class.new do + def each + yield "Failed request body" + end + + def status + raise NoMethodError, "undefined method `status`" + end + end.new + + yielded_chunks = [] + expect do + request.send(:process_response_chunks, response, error_body) do |chunk| + yielded_chunks << chunk + end + end.not_to raise_error + + expect(error_body).to eq("Failed request body") + expect(yielded_chunks).to be_empty + end + end end