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 d8776fd3..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(Error, "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 58f14c30..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" @@ -155,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 322e25b3..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::Error" do - expect { response.parse }.to raise_error HTTP::Error + 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