Improve federation instance error diagnostics (#350)

This commit is contained in:
l5y
2025-10-15 18:35:22 +02:00
committed by GitHub
parent 49f08a7f75
commit db7b67d859
2 changed files with 69 additions and 1 deletions

View File

@@ -310,7 +310,30 @@ module PotatoMesh
end
end
rescue StandardError => e
raise InstanceFetchError, e.message
raise_instance_fetch_error(e)
end
# Build a human readable error message for a failed instance request.
#
# @param error [StandardError] failure raised while performing the request.
# @return [String] description including the error class when necessary.
def instance_fetch_error_message(error)
message = error.message.to_s.strip
class_name = error.class.name || error.class.to_s
return class_name if message.empty?
message.include?(class_name) ? message : "#{class_name}: #{message}"
end
# Raise an InstanceFetchError that preserves the original context.
#
# @param error [StandardError] failure raised while performing the request.
# @return [void]
def raise_instance_fetch_error(error)
message = instance_fetch_error_message(error)
wrapped = InstanceFetchError.new(message)
wrapped.set_backtrace(error.backtrace)
raise wrapped
end
def fetch_instance_json(domain, path)

View File

@@ -161,4 +161,49 @@ RSpec.describe PotatoMesh::App::Federation do
expect(http.verify_callback).to be_nil
end
end
describe ".perform_instance_http_request" do
let(:uri) { URI.parse("https://remote.example.com/api") }
let(:http_client) { instance_double(Net::HTTP) }
before do
allow(federation_helpers).to receive(:build_remote_http_client).with(uri).and_return(http_client)
end
it "wraps errors that omit a message with the error class name" do
stub_const(
"RemoteTcpFailure",
Class.new(StandardError) do
def message
""
end
end,
)
allow(http_client).to receive(:start).and_raise(RemoteTcpFailure.new)
expect do
federation_helpers.send(:perform_instance_http_request, uri)
end.to raise_error(PotatoMesh::App::InstanceFetchError, "RemoteTcpFailure")
end
it "includes the error class name when the message omits it" do
allow(http_client).to receive(:start).and_raise(OpenSSL::SSL::SSLError.new("handshake failed"))
expect do
federation_helpers.send(:perform_instance_http_request, uri)
end.to raise_error(
PotatoMesh::App::InstanceFetchError,
"OpenSSL::SSL::SSLError: handshake failed",
)
end
it "preserves messages that already include the error class" do
allow(http_client).to receive(:start).and_raise(Net::ReadTimeout.new)
expect do
federation_helpers.send(:perform_instance_http_request, uri)
end.to raise_error(PotatoMesh::App::InstanceFetchError, "Net::ReadTimeout")
end
end
end