Skip to content

Commit

Permalink
Add Fountain::UnexpectedHTTPError to provide more error context (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
abrom committed Aug 2, 2024
1 parent bd2402a commit 80619dc
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ RSpec/ExampleLength:

RSpec/MultipleExpectations:
Max: 5

RSpec/NestedGroups:
Max: 4
25 changes: 25 additions & 0 deletions lib/fountain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,31 @@ class AuthenticationError < HTTPError; end

class InvalidMethodError < HTTPError; end

#
# Unexpected HTTP Error
#
class UnexpectedHTTPError < HTTPError
def initialize(response)
@response = response
super("Unexpected http response code: #{response.code}")
end

def response_code
@response.code
end

def parsed_body
JSON.parse(@response.body)
rescue JSON::ParserError
@response.body
end

def response_message
body = parsed_body
body['message'] if body.is_a? Hash
end
end

class JsonParseError < Error; end

class MissingApiKeyError < Error; end
Expand Down
2 changes: 1 addition & 1 deletion lib/fountain/api/request_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def check_response(response, expected_response = nil)
when *[expected_response].flatten then nil
when Net::HTTPUnauthorized then raise Fountain::AuthenticationError
when Net::HTTPNotFound then raise Fountain::NotFoundError
else raise HTTPError, "Invalid http response code: #{response.code}"
else raise Fountain::UnexpectedHTTPError, response
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/fountain/api/applicants_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@
invalid_arg: 'should not be included',
funnel_id: 'funnel-id'
)
end.to raise_error Fountain::HTTPError, 'Invalid http response code: 422'
end.to raise_error Fountain::UnexpectedHTTPError, 'Unexpected http response code: 422'
end
end

Expand Down
81 changes: 81 additions & 0 deletions spec/fountain/fountain_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# frozen_string_literal: true

require 'spec_helper'

describe Fountain do
describe Fountain::Error do
it { is_expected.to be_a StandardError }
end

describe Fountain::HTTPError do
it { is_expected.to be_a Fountain::Error }
end

describe Fountain::NotFoundError do
it { is_expected.to be_a Fountain::HTTPError }
end

describe Fountain::AuthenticationError do
it { is_expected.to be_a Fountain::HTTPError }
end

describe Fountain::InvalidMethodError do
it { is_expected.to be_a Fountain::HTTPError }
end

describe Fountain::UnexpectedHTTPError do
subject(:unexpected_http_error) { described_class.new(response) }

let(:response) do
Net::HTTPUnprocessableEntity.new('1.1', '422', 'Unprocessable Entity').tap do |r|
r.body = response_body
r.instance_variable_set :@read, true
end
end
let(:response_body) { '{"message": "Applicant is already on this stage"}' }

it { is_expected.to be_a Fountain::HTTPError }

describe '#response_code' do
subject(:response_code) { unexpected_http_error.response_code }

it { is_expected.to eq '422' }
end

describe '#parsed_body' do
subject(:parsed_body) { unexpected_http_error.parsed_body }

it { is_expected.to eq('message' => 'Applicant is already on this stage') }

context 'when the response body is not JSON' do
let(:response_body) { 'This isnt JSON' }

it { is_expected.to eq 'This isnt JSON' }
end
end

describe '#response_message' do
subject(:response_message) { unexpected_http_error.response_message }

it { is_expected.to eq 'Applicant is already on this stage' }

context 'when the response body is not JSON' do
let(:response_body) { 'This isnt JSON' }

it { is_expected.to be_nil }
end
end
end

describe Fountain::JsonParseError do
it { is_expected.to be_a Fountain::Error }
end

describe Fountain::MissingApiKeyError do
it { is_expected.to be_a Fountain::Error }
end

describe Fountain::StatusError do
it { is_expected.to be_a Fountain::Error }
end
end

0 comments on commit 80619dc

Please sign in to comment.