From 44e6087755549410889cee8ea02bfb88557362bb Mon Sep 17 00:00:00 2001 From: TheBlackArroVV Date: Tue, 10 Jun 2025 12:17:00 +0100 Subject: [PATCH 1/2] feat: introduce better error for wrong mime type --- lib/http/mime_type.rb | 2 +- lib/http/response.rb | 3 +++ spec/lib/http/response_spec.rb | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/http/mime_type.rb b/lib/http/mime_type.rb index d8776fd3..bd2802dd 100644 --- a/lib/http/mime_type.rb +++ b/lib/http/mime_type.rb @@ -35,7 +35,7 @@ def register_adapter(type, adapter) # @raise [Error] if no adapter found # @return [Class] def [](type) - adapters[normalize type] || raise(Error, "Unknown MIME type: #{type}") + adapters[normalize type] || raise(HTTP::Response::UnexpectedMimeTypeError, "Unknown MIME type: #{type}") end # Register a shortcut for MIME type diff --git a/lib/http/response.rb b/lib/http/response.rb index 58f14c30..1d3c1c9d 100644 --- a/lib/http/response.rb +++ b/lib/http/response.rb @@ -12,6 +12,9 @@ module HTTP class Response + class ParseError < Error; end + class UnexpectedMimeTypeError < ParseError; end + extend Forwardable include HTTP::Headers::Mixin diff --git a/spec/lib/http/response_spec.rb b/spec/lib/http/response_spec.rb index 322e25b3..72c3756d 100644 --- a/spec/lib/http/response_spec.rb +++ b/spec/lib/http/response_spec.rb @@ -109,8 +109,8 @@ context "with unknown content type" do let(:content_type) { "application/deadbeef" } - it "raises HTTP::Error" do - expect { response.parse }.to raise_error HTTP::Error + it "raises HTTP::Response::UnexpectedMimeTypeError" do + expect { response.parse }.to raise_error HTTP::Response::UnexpectedMimeTypeError end end From f736073d1fe97c7cf2ace8804bebdbcea3a1e76c Mon Sep 17 00:00:00 2001 From: Alexey Zapparov Date: Tue, 10 Jun 2025 20:38:58 +0200 Subject: [PATCH 2/2] review: Improve exceptions hierarchy --- lib/http/errors.rb | 7 +++++++ lib/http/mime_type.rb | 4 +++- lib/http/response.rb | 6 +++--- spec/lib/http/response_spec.rb | 13 +++++++++++-- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/http/errors.rb b/lib/http/errors.rb index dcbe5a13..373fab49 100644 --- a/lib/http/errors.rb +++ b/lib/http/errors.rb @@ -32,6 +32,13 @@ def initialize(response) end end + # Raised when `Response#parse` fails due to any underlying reason (unexpected + # MIME type, or decoder fails). See `Exception#cause` for the original exception. + class ParseError < ResponseError; end + + # Requested MimeType adapter not found. + class UnsupportedMimeTypeError < Error; end + # Generic Timeout error class TimeoutError < Error; end diff --git a/lib/http/mime_type.rb b/lib/http/mime_type.rb index bd2802dd..2890ab4d 100644 --- a/lib/http/mime_type.rb +++ b/lib/http/mime_type.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "http/errors" + module HTTP # MIME type encode/decode adapters module MimeType @@ -35,7 +37,7 @@ def register_adapter(type, adapter) # @raise [Error] if no adapter found # @return [Class] def [](type) - adapters[normalize type] || raise(HTTP::Response::UnexpectedMimeTypeError, "Unknown MIME type: #{type}") + adapters[normalize type] || raise(UnsupportedMimeTypeError, "Unknown MIME type: #{type}") end # Register a shortcut for MIME type diff --git a/lib/http/response.rb b/lib/http/response.rb index 1d3c1c9d..6212b5a6 100644 --- a/lib/http/response.rb +++ b/lib/http/response.rb @@ -2,6 +2,7 @@ require "forwardable" +require "http/errors" require "http/headers" require "http/content_type" require "http/mime_type" @@ -12,9 +13,6 @@ module HTTP class Response - class ParseError < Error; end - class UnexpectedMimeTypeError < ParseError; end - extend Forwardable include HTTP::Headers::Mixin @@ -158,6 +156,8 @@ def chunked? # @return [Object] def parse(type = nil) MimeType[type || mime_type].decode to_s + rescue => e + raise ParseError, e.message end # Inspect a response diff --git a/spec/lib/http/response_spec.rb b/spec/lib/http/response_spec.rb index 72c3756d..fc4bbd7e 100644 --- a/spec/lib/http/response_spec.rb +++ b/spec/lib/http/response_spec.rb @@ -109,8 +109,8 @@ context "with unknown content type" do let(:content_type) { "application/deadbeef" } - it "raises HTTP::Response::UnexpectedMimeTypeError" do - expect { response.parse }.to raise_error HTTP::Response::UnexpectedMimeTypeError + it "raises HTTP::ParseError" do + expect { response.parse }.to raise_error HTTP::ParseError end end @@ -125,6 +125,15 @@ expect(response.parse(:json)).to eq "foo" => "bar" end end + + context "when underlying parser fails" do + let(:content_type) { "application/deadbeef" } + let(:body) { "" } + + it "raises HTTP::ParseError" do + expect { response.parse }.to raise_error HTTP::ParseError + end + end end describe "#flush" do