From 04a760d6c6847ab3d52861de761e9c51e2e33271 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Thu, 30 Jul 2026 13:41:18 +1200 Subject: [PATCH] Map HTTP/2 body internal errors --- lib/async/http/protocol/http2/input.rb | 8 ++++++ .../connection_close_with_active_streams.rb | 25 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/lib/async/http/protocol/http2/input.rb b/lib/async/http/protocol/http2/input.rb index d6b7f5a..1c89683 100644 --- a/lib/async/http/protocol/http2/input.rb +++ b/lib/async/http/protocol/http2/input.rb @@ -4,6 +4,8 @@ # Copyright, 2020-2024, by Samuel Williams. require "protocol/http/body/writable" +require "protocol/http/error" +require "protocol/http2/error" module Async module HTTP @@ -41,6 +43,12 @@ def read end return chunk + rescue ::Protocol::HTTP2::StreamError => error + if error.code == ::Protocol::HTTP2::Error::INTERNAL_ERROR + raise ::Protocol::HTTP::RemoteError, error.message + end + + raise end end end diff --git a/test/async/http/protocol/http2/connection_close_with_active_streams.rb b/test/async/http/protocol/http2/connection_close_with_active_streams.rb index dcc24b9..b0c39ef 100644 --- a/test/async/http/protocol/http2/connection_close_with_active_streams.rb +++ b/test/async/http/protocol/http2/connection_close_with_active_streams.rb @@ -69,6 +69,31 @@ end.wait end + it "maps a remote internal error while reading the response body" do + Async do |task| + client_connection = Async::HTTP::Protocol::HTTP2::Client.new(client_stream) + client_connection.open! + + response = client_connection.create_response + request = Protocol::HTTP::Request.new("https", "example.com", "GET", "/") + client_connection.write_request(response, request) + response.stream.receive_initial_headers([[":status", "200"]], false) + + client_connection.read_response(response) + response.stream.close!(Protocol::HTTP2::INTERNAL_ERROR) + + expect do + response.body.read + end.to raise_exception(Protocol::HTTP::RemoteError).and( + have_attributes( + cause: be_a(Protocol::HTTP2::StreamError).and( + have_attributes(code: be == Protocol::HTTP2::INTERNAL_ERROR) + ) + ) + ) + end.wait + end + it "does not raise error when connection closes without active streams" do Async do |task| # Create client connection