when bubbling up errors in the connection, handle request error directly

instead of expecting it to be contained within it, and therefore handled explicitly. sometimes they may not.
This commit is contained in:
HoneyryderChuck 2024-07-22 14:53:53 +01:00
parent 002459b9b6
commit 74fc7bf77d
7 changed files with 49 additions and 27 deletions

View File

@ -195,15 +195,19 @@ module Datadog::Tracing
# that the tracing logic hasn't been injected yet; in such cases, the approximate # that the tracing logic hasn't been injected yet; in such cases, the approximate
# initial resolving time is collected from the connection, and used as span start time, # initial resolving time is collected from the connection, and used as span start time,
# and the tracing object in inserted before the on response callback is called. # and the tracing object in inserted before the on response callback is called.
def handle_error(error) def handle_error(error, request = nil)
return super unless Datadog::Tracing.enabled? return super unless Datadog::Tracing.enabled?
return super unless error.respond_to?(:connection) return super unless error.respond_to?(:connection)
@pending.each do |request| @pending.each do |req|
RequestTracer.new(request).call(error.connection.init_time) next if request and request == req
RequestTracer.new(req).call(error.connection.init_time)
end end
RequestTracer.new(request).call(error.connection.init_time) if request
super super
end end
end end

View File

@ -641,7 +641,7 @@ module HTTPX
end end
end end
def on_error(error) def on_error(error, request = nil)
if error.instance_of?(TimeoutError) if error.instance_of?(TimeoutError)
# inactive connections do not contribute to the select loop, therefore # inactive connections do not contribute to the select loop, therefore
@ -655,17 +655,25 @@ module HTTPX
error = error.to_connection_error if connecting? error = error.to_connection_error if connecting?
end end
handle_error(error) handle_error(error, request)
reset reset
end end
def handle_error(error) def handle_error(error, request = nil)
parser.handle_error(error) if @parser && parser.respond_to?(:handle_error) parser.handle_error(error, request) if @parser && parser.respond_to?(:handle_error)
while (request = @pending.shift) while (req = @pending.shift)
response = ErrorResponse.new(request, error) next if request && req == request
request.response = response
request.emit(:response, response) response = ErrorResponse.new(req, error)
req.response = response
req.emit(:response, response)
end end
return unless request
response = ErrorResponse.new(request, error)
request.response = response
request.emit(:response, response)
end end
def set_request_timeouts(request) def set_request_timeouts(request)
@ -709,7 +717,8 @@ module HTTPX
@write_buffer.clear @write_buffer.clear
error = WriteTimeoutError.new(request, nil, write_timeout) error = WriteTimeoutError.new(request, nil, write_timeout)
on_error(error)
on_error(error, request)
end end
def read_timeout_callback(request, read_timeout, error_type = ReadTimeoutError) def read_timeout_callback(request, read_timeout, error_type = ReadTimeoutError)
@ -719,7 +728,8 @@ module HTTPX
@write_buffer.clear @write_buffer.clear
error = error_type.new(request, request.response, read_timeout) error = error_type.new(request, request.response, read_timeout)
on_error(error)
on_error(error, request)
end end
def set_request_timeout(request, timeout, start_event, finish_events, &callback) def set_request_timeout(request, timeout, start_event, finish_events, &callback)

View File

@ -197,7 +197,7 @@ module HTTPX
end end
end end
def handle_error(ex) def handle_error(ex, request = nil)
if (ex.is_a?(EOFError) || ex.is_a?(TimeoutError)) && @request && @request.response && if (ex.is_a?(EOFError) || ex.is_a?(TimeoutError)) && @request && @request.response &&
!@request.response.headers.key?("content-length") && !@request.response.headers.key?("content-length") &&
!@request.response.headers.key?("transfer-encoding") !@request.response.headers.key?("transfer-encoding")
@ -211,11 +211,15 @@ module HTTPX
if @pipelining if @pipelining
catch(:called) { disable } catch(:called) { disable }
else else
@requests.each do |request| @requests.each do |req|
emit(:error, request, ex) next if request && request == req
emit(:error, req, ex)
end end
@pending.each do |request| @pending.each do |req|
emit(:error, request, ex) next if request && request == req
emit(:error, req, ex)
end end
end end
end end

View File

@ -123,7 +123,7 @@ module HTTPX
end end
end end
def handle_error(ex) def handle_error(ex, request = nil)
if ex.instance_of?(TimeoutError) && !@handshake_completed && @connection.state != :closed if ex.instance_of?(TimeoutError) && !@handshake_completed && @connection.state != :closed
@connection.goaway(:settings_timeout, "closing due to settings timeout") @connection.goaway(:settings_timeout, "closing due to settings timeout")
emit(:close_handshake) emit(:close_handshake)
@ -131,11 +131,15 @@ module HTTPX
settings_ex.set_backtrace(ex.backtrace) settings_ex.set_backtrace(ex.backtrace)
ex = settings_ex ex = settings_ex
end end
@streams.each_key do |request| @streams.each_key do |req|
emit(:error, request, ex) next if request && request == req
emit(:error, req, ex)
end end
@pending.each do |request| @pending.each do |req|
emit(:error, request, ex) next if request && request == req
emit(:error, req, ex)
end end
end end

View File

@ -119,9 +119,9 @@ module HTTPX
def build_socket: (?Array[ipaddr]? addrs) -> (TCP | SSL | UNIX) def build_socket: (?Array[ipaddr]? addrs) -> (TCP | SSL | UNIX)
def on_error: (HTTPX::TimeoutError | Error | StandardError error) -> void def on_error: (HTTPX::TimeoutError | Error | StandardError error, ?Request? request) -> void
def handle_error: (StandardError error) -> void def handle_error: (StandardError error, ?Request? request) -> void
def purge_after_closed: () -> void def purge_after_closed: () -> void

View File

@ -38,7 +38,7 @@ module HTTPX
def consume: () -> void def consume: () -> void
def handle_error: (StandardError ex) -> void def handle_error: (StandardError ex, ?Request? request) -> void
def on_start: () -> void def on_start: () -> void

View File

@ -32,7 +32,7 @@ module HTTPX
def consume: () -> void def consume: () -> void
def handle_error: (StandardError ex) -> void def handle_error: (StandardError ex, ?Request? request) -> void
def ping: () -> void def ping: () -> void