From 6e091adaa45703ed0f1c640676c7ffe548a23853 Mon Sep 17 00:00:00 2001 From: ellnix <103502144+ellnix@users.noreply.github.com> Date: Wed, 17 Jan 2024 11:32:52 +0100 Subject: [PATCH 1/3] Test version_error_handler with realistic data 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 `@http_body` as the server http body which causes ApiError to attempt to parse it again as JSON, throwing a TypeError. --- spec/meilisearch/utils_spec.rb | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/spec/meilisearch/utils_spec.rb b/spec/meilisearch/utils_spec.rb index e4d82507..f757b025 100644 --- a/spec/meilisearch/utils_spec.rb +++ b/spec/meilisearch/utils_spec.rb @@ -67,10 +67,25 @@ 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 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 @@ -78,7 +93,7 @@ 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 From 5c40b93c87ab85f0157f02552c7811591d8e7f29 Mon Sep 17 00:00:00 2001 From: ellnix <103502144+ellnix@users.noreply.github.com> Date: Wed, 17 Jan 2024 12:05:43 +0100 Subject: [PATCH 2/3] Update ApiError to accept a hash as http_body Allows easier propagation of ApiError. --- lib/meilisearch/error.rb | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/meilisearch/error.rb b/lib/meilisearch/error.rb index 01d3776f..01420f09 100644 --- a/lib/meilisearch/error.rb +++ b/lib/meilisearch/error.rb @@ -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 ||= '' + @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', '') @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 From bbcfa7fcd906e68abdde653f65b8d84683ea2acb Mon Sep 17 00:00:00 2001 From: ellnix <103502144+ellnix@users.noreply.github.com> Date: Wed, 17 Jan 2024 12:15:32 +0100 Subject: [PATCH 3/3] Add spec for ApiError with html body --- spec/meilisearch/utils_spec.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/meilisearch/utils_spec.rb b/spec/meilisearch/utils_spec.rb index f757b025..ffeea67a 100644 --- a/spec/meilisearch/utils_spec.rb +++ b/spec/meilisearch/utils_spec.rb @@ -82,6 +82,14 @@ 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', '

405 Error

') + 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