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
# 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.
def handle_error(error)
def handle_error(error, request = nil)
return super unless Datadog::Tracing.enabled?
return super unless error.respond_to?(:connection)
@pending.each do |request|
RequestTracer.new(request).call(error.connection.init_time)
@pending.each do |req|
next if request and request == req
RequestTracer.new(req).call(error.connection.init_time)
end
RequestTracer.new(request).call(error.connection.init_time) if request
super
end
end

View File

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

View File

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

View File

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

View File

@ -119,9 +119,9 @@ module HTTPX
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

View File

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

View File

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