Skip to content

Commit 5e2d354

Browse files
Merge #515
515: Fix error propagating logic r=ellnix a=ellnix # Pull Request ## Related issue Fixes #513 ## What does this PR do? - Meilisearch::ApiError parses a server's JSON response into its ``@http_body`` instance variable which stores a hash. - When `version_error_handler` propagates `ApiError`, it passes the ``@http_body`` hash as http body which causes `ApiError` to attempt to parse it again as JSON, throwing a `TypeError`. - This PR makes the `http_body` parameter polymorphic, allowing either a hash or a JSON string to be passed. Co-authored-by: ellnix <[email protected]>
2 parents 5adacb7 + bbcfa7f commit 5e2d354

File tree

2 files changed

+39
-12
lines changed

2 files changed

+39
-12
lines changed

lib/meilisearch/error.rb

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,30 @@ class ApiError < Error
2121
alias link ms_link
2222

2323
def initialize(http_code, http_message, http_body)
24-
get_meilisearch_error_info(http_body) unless http_body.nil? || http_body.empty?
2524
@http_code = http_code
2625
@http_message = http_message
27-
@ms_message ||= 'MeiliSearch API has not returned any error message'
28-
@ms_link ||= '<no documentation link found>'
26+
@http_body = parse_body(http_body)
27+
@ms_code = @http_body['code']
28+
@ms_type = @http_body['type']
29+
@ms_message = @http_body.fetch('message', 'MeiliSearch API has not returned any error message')
30+
@ms_link = @http_body.fetch('link', '<no documentation link found>')
2931
@message = "#{http_code} #{http_message} - #{@ms_message}. See #{ms_link}."
3032
super(details)
3133
end
3234

33-
def get_meilisearch_error_info(http_body)
34-
@http_body = JSON.parse(http_body)
35-
@ms_code = @http_body['code']
36-
@ms_message = @http_body['message']
37-
@ms_type = @http_body['type']
38-
@ms_link = @http_body['link']
35+
def parse_body(http_body)
36+
if http_body.respond_to?(:to_hash)
37+
http_body.to_hash
38+
elsif http_body.respond_to?(:to_str)
39+
JSON.parse(http_body.to_str)
40+
else
41+
{}
42+
end
3943
rescue JSON::ParserError
4044
# We might receive a JSON::ParserError when, for example, MeiliSearch is running behind
4145
# some proxy (ELB or Nginx, for example), and the request timeouts, returning us
4246
# a raw HTML body instead of a JSON as we were expecting
43-
@ms_message = "The server has not returned a valid JSON HTTP body: #{http_body}"
47+
{ 'message' => "The server has not returned a valid JSON HTTP body: #{http_body}" }
4448
end
4549

4650
def details

spec/meilisearch/utils_spec.rb

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,41 @@
6767
end
6868

6969
describe '.version_error_handler' do
70+
let(:http_body) do
71+
{ 'message' => 'Was expecting an operation',
72+
'code' => 'invalid_document_filter',
73+
'type' => 'invalid_request',
74+
'link' => 'https://docs.meilisearch.com/errors#invalid_document_filter' }
75+
end
76+
7077
it 'spawns same error message' do
7178
expect do
7279
described_class.version_error_handler(:my_method) do
73-
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', {})
80+
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', http_body)
81+
end
82+
end.to raise_error(MeiliSearch::ApiError, /I came from Meili server/)
83+
end
84+
85+
it 'spawns same error message with html body' do
86+
expect do
87+
described_class.version_error_handler(:my_method) do
88+
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', '<html><h1>405 Error</h1></html>')
89+
end
90+
end.to raise_error(MeiliSearch::ApiError, /I came from Meili server/)
91+
end
92+
93+
it 'spawns same error message with no body' do
94+
expect do
95+
described_class.version_error_handler(:my_method) do
96+
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', nil)
7497
end
7598
end.to raise_error(MeiliSearch::ApiError, /I came from Meili server/)
7699
end
77100

78101
it 'spawns message with version hint' do
79102
expect do
80103
described_class.version_error_handler(:my_method) do
81-
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', {})
104+
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', http_body)
82105
end
83106
end.to raise_error(MeiliSearch::ApiError, /that `my_method` call requires/)
84107
end

0 commit comments

Comments
 (0)