diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f0750b..7176bcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## [Released] +## [0.12.0] - 2025-06-26 + +- Add timeout error + ## [0.11.0] - 2025-06-25 - Add create report request diff --git a/Gemfile.lock b/Gemfile.lock index 5b4ecfa..bf27078 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - boapi (0.10.0) + boapi (0.12.0) faraday (> 0.7.6, < 1.0) faraday_middleware (> 0.1, < 1.0) @@ -74,6 +74,7 @@ GEM PLATFORMS -darwin-21 + -darwin-24 x86_64-darwin-21 x86_64-darwin-23 x86_64-linux diff --git a/lib/boapi/client.rb b/lib/boapi/client.rb index 43da2f6..3ff2d3f 100644 --- a/lib/boapi/client.rb +++ b/lib/boapi/client.rb @@ -85,12 +85,22 @@ def create_report(params) send_request(:post, '/api/v2/reports', params) end + # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/MethodLength def send_request(method, path, params = nil) response = begin connection.public_send(method, path, params) do |request| request.headers['Content-Type'] = 'application/json' if %i[post put patch].include?(method) end + rescue Faraday::ConnectionFailed => e + Boapi.configuration.logger.error("BOAPI::CLIENT::FARADAY::ERROR::CONNECTION_FAILED :: #{e}") + + build_connection_error_body(e) + rescue Faraday::TimeoutError => e + Boapi.configuration.logger.error("BOAPI::CLIENT::FARADAY::ERROR::READ_TIMEOUT :: #{e}") + + build_read_timeout_error_body(e) rescue Faraday::Error => e Boapi.configuration.logger.error("BOAPI::CLIENT::FARADAY::ERROR :: #{e}") @@ -100,6 +110,8 @@ def send_request(method, path, params = nil) Boapi::Response.new(response) end + # rubocop:enable Metrics/AbcSize + # rubocop:enable Metrics/MethodLength def connection @connection ||= build_connection end @@ -142,6 +154,34 @@ def build_error_body(error_message) ) end + def build_read_timeout_error_body(error_message) + Struct.new(:status, :success?, :body, keyword_init: true).new( + status: 504, + body: { + 'error' => { + 'code' => 'gateway_timeout', + 'friendly_message' => 'ReadTimeout error occurred', + 'message' => error_message.to_s + } + }, + success?: false + ) + end + + def build_connection_error_body(error_message) + Struct.new(:status, :success?, :body, keyword_init: true).new( + status: 502, + body: { + 'error' => { + 'code' => 'bad_gateway', + 'friendly_message' => 'Connection error', + 'message' => error_message.to_s + } + }, + success?: false + ) + end + # rubocop:enable Metrics/MethodLength end # rubocop:enable Metrics/ClassLength diff --git a/lib/boapi/version.rb b/lib/boapi/version.rb index a949cba..7f8e863 100644 --- a/lib/boapi/version.rb +++ b/lib/boapi/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Boapi - VERSION = '0.10.0' + VERSION = '0.12.0' end diff --git a/spec/boapi/client_spec.rb b/spec/boapi/client_spec.rb index 7cb84e7..f121cf7 100644 --- a/spec/boapi/client_spec.rb +++ b/spec/boapi/client_spec.rb @@ -24,6 +24,42 @@ end end + context 'when connection error' do + let(:response) { Boapi::Client.new(account_id: account_id, account_secret: account_secret).health } + let(:url) { "#{Boapi.configuration.api_host}/api/health" } + + before do + stub_request(:get, url) + .to_raise(Faraday::ConnectionFailed.new('Failed to connect')) + end + + it 'returns connection_failed response' do + expect(response.status).to be 502 + + expect(response.success?).to be false + expect(response.error?).to be true + expect(response.error).to eq SupportFixtures.bad_gateway_response + end + end + + context 'when timeout error' do + let(:response) { Boapi::Client.new(account_id: account_id, account_secret: account_secret).health } + let(:url) { "#{Boapi.configuration.api_host}/api/health" } + + before do + stub_request(:get, url) + .to_raise(Faraday::TimeoutError.new('Timeout')) + end + + it 'returns connection_failed response' do + expect(response.status).to be 504 + + expect(response.success?).to be false + expect(response.error?).to be true + expect(response.error).to eq SupportFixtures.gateway_timeout_response + end + end + describe '.health' do let(:response) { Boapi::Client.new(account_id: account_id, account_secret: account_secret).health } let(:http_status) { 200 } diff --git a/spec/fixtures/support_fixtures.rb b/spec/fixtures/support_fixtures.rb index 5b0f07a..8730839 100644 --- a/spec/fixtures/support_fixtures.rb +++ b/spec/fixtures/support_fixtures.rb @@ -21,4 +21,20 @@ def failed_without_authentification_response_message def failed_without_authentification_response %({"error":#{failed_without_authentification_response_message.to_json}}) end + + def bad_gateway_response + { + 'code' => 'bad_gateway', + 'friendly_message' => 'Connection error', + 'message' => 'Failed to connect' + } + end + + def gateway_timeout_response + { + 'code' => 'gateway_timeout', + 'friendly_message' => 'ReadTimeout error occurred', + 'message' => 'Timeout' + } + end end