Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix error propagating logic #515

Merged
merged 3 commits into from Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 14 additions & 10 deletions lib/meilisearch/error.rb
Expand Up @@ -21,26 +21,30 @@ class ApiError < Error
alias link ms_link

def initialize(http_code, http_message, http_body)
get_meilisearch_error_info(http_body) unless http_body.nil? || http_body.empty?
@http_code = http_code
@http_message = http_message
@ms_message ||= 'MeiliSearch API has not returned any error message'
@ms_link ||= '<no documentation link found>'
@http_body = parse_body(http_body)
@ms_code = @http_body['code']
@ms_type = @http_body['type']
@ms_message = @http_body.fetch('message', 'MeiliSearch API has not returned any error message')
@ms_link = @http_body.fetch('link', '<no documentation link found>')
@message = "#{http_code} #{http_message} - #{@ms_message}. See #{ms_link}."
super(details)
end

def get_meilisearch_error_info(http_body)
@http_body = JSON.parse(http_body)
@ms_code = @http_body['code']
@ms_message = @http_body['message']
@ms_type = @http_body['type']
@ms_link = @http_body['link']
def parse_body(http_body)
if http_body.respond_to?(:to_hash)
http_body.to_hash
elsif http_body.respond_to?(:to_str)
JSON.parse(http_body.to_str)
else
{}
end
rescue JSON::ParserError
# We might receive a JSON::ParserError when, for example, MeiliSearch is running behind
# some proxy (ELB or Nginx, for example), and the request timeouts, returning us
# a raw HTML body instead of a JSON as we were expecting
@ms_message = "The server has not returned a valid JSON HTTP body: #{http_body}"
{ 'message' => "The server has not returned a valid JSON HTTP body: #{http_body}" }
end

def details
Expand Down
27 changes: 25 additions & 2 deletions spec/meilisearch/utils_spec.rb
Expand Up @@ -67,18 +67,41 @@
end

describe '.version_error_handler' do
let(:http_body) do
{ 'message' => 'Was expecting an operation',
'code' => 'invalid_document_filter',
'type' => 'invalid_request',
'link' => 'https://docs.meilisearch.com/errors#invalid_document_filter' }
end

it 'spawns same error message' do
expect do
described_class.version_error_handler(:my_method) do
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', {})
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', http_body)
end
end.to raise_error(MeiliSearch::ApiError, /I came from Meili server/)
end

it 'spawns same error message with html body' do
expect do
described_class.version_error_handler(:my_method) do
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', '<html><h1>405 Error</h1></html>')
end
end.to raise_error(MeiliSearch::ApiError, /I came from Meili server/)
end

it 'spawns same error message with no body' do
expect do
described_class.version_error_handler(:my_method) do
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', nil)
end
end.to raise_error(MeiliSearch::ApiError, /I came from Meili server/)
end

it 'spawns message with version hint' do
expect do
described_class.version_error_handler(:my_method) do
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', {})
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', http_body)
end
end.to raise_error(MeiliSearch::ApiError, /that `my_method` call requires/)
end
Expand Down