diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb index ec60e2419..824751910 100644 --- a/app/controllers/users/dossiers_controller.rb +++ b/app/controllers/users/dossiers_controller.rb @@ -189,7 +189,7 @@ module Users etablissement = begin APIEntrepriseService.create_etablissement(@dossier, sanitized_siret, current_user.id) rescue => error - if error.try(:network_error?) && !APIEntrepriseService.api_insee_up? + if error.is_a?(APIEntreprise::API::Error::ServiceUnavailable) || (error.try(:network_error?) && !APIEntrepriseService.api_insee_up?) # TODO: notify ops APIEntrepriseService.create_etablissement_as_degraded_mode(@dossier, sanitized_siret, current_user.id) else diff --git a/app/lib/api_entreprise/api.rb b/app/lib/api_entreprise/api.rb index 3752ed49e..8b7fb819a 100644 --- a/app/lib/api_entreprise/api.rb +++ b/app/lib/api_entreprise/api.rb @@ -127,10 +127,10 @@ class APIEntreprise::API raise Error::ResourceNotFound.new(response) elsif response.code == 400 raise Error::BadFormatRequest.new(response) + elsif service_unavailable?(response) + raise Error::ServiceUnavailable.new(response) elsif response.code == 502 raise Error::BadGateway.new(response) - elsif response.code == 503 - raise Error::ServiceUnavailable.new(response) elsif response.timed_out? raise Error::TimedOut.new(response) else @@ -138,6 +138,19 @@ class APIEntreprise::API end end + def service_unavailable?(response) + return true if response.code == 503 + if response.code == 502 || response.code == 504 + parse_response_errors(response).any? { _1.is_a?(Hash) && ["01000", "01001", "01002"].include?(_1[:code]) } + end + end + + def parse_response_errors(response) + JSON.parse(response.body, symbolize_names: true).fetch(:errors, []) + rescue JSON::ParserError + [] + end + def make_url(resource_name, siret_or_siren = nil) [API_ENTREPRISE_URL, format(resource_name, id: siret_or_siren)].compact.join("/") end diff --git a/spec/fixtures/files/api_entreprise/error_code_01000.json b/spec/fixtures/files/api_entreprise/error_code_01000.json new file mode 100644 index 000000000..6ee2b7d84 --- /dev/null +++ b/spec/fixtures/files/api_entreprise/error_code_01000.json @@ -0,0 +1,3 @@ +{ + "errors": [{ "code": "01000" }] +} diff --git a/spec/fixtures/files/api_entreprise/error_code_01001.json b/spec/fixtures/files/api_entreprise/error_code_01001.json new file mode 100644 index 000000000..e23909ac6 --- /dev/null +++ b/spec/fixtures/files/api_entreprise/error_code_01001.json @@ -0,0 +1,3 @@ +{ + "errors": [{ "code": "01001" }] +} diff --git a/spec/fixtures/files/api_entreprise/error_code_01002.json b/spec/fixtures/files/api_entreprise/error_code_01002.json new file mode 100644 index 000000000..6454a0c88 --- /dev/null +++ b/spec/fixtures/files/api_entreprise/error_code_01002.json @@ -0,0 +1,3 @@ +{ + "errors": [{ "code": "01002" }] +} diff --git a/spec/lib/api_entreprise/api_spec.rb b/spec/lib/api_entreprise/api_spec.rb index 39cde9eda..fc9b4fbd5 100644 --- a/spec/lib/api_entreprise/api_spec.rb +++ b/spec/lib/api_entreprise/api_spec.rb @@ -24,6 +24,36 @@ describe APIEntreprise::API do end end + context 'when the service reponds with 01000 code' do + let(:siren) { '111111111' } + let(:status) { 502 } + let(:body) { Rails.root.join('spec/fixtures/files/api_entreprise/error_code_01000.json').read } + + it 'raises APIEntreprise::API::Error::RequestFailed' do + expect { subject }.to raise_error(APIEntreprise::API::Error::ServiceUnavailable) + end + end + + context 'when the service reponds with 01001 code' do + let(:siren) { '111111111' } + let(:status) { 502 } + let(:body) { Rails.root.join('spec/fixtures/files/api_entreprise/error_code_01001.json').read } + + it 'raises APIEntreprise::API::Error::RequestFailed' do + expect { subject }.to raise_error(APIEntreprise::API::Error::ServiceUnavailable) + end + end + + context 'when the service reponds with 01002 code' do + let(:siren) { '111111111' } + let(:status) { 504 } + let(:body) { Rails.root.join('spec/fixtures/files/api_entreprise/error_code_01002.json').read } + + it 'raises APIEntreprise::API::Error::RequestFailed' do + expect { subject }.to raise_error(APIEntreprise::API::Error::ServiceUnavailable) + end + end + context 'when siren does not exist' do let(:siren) { '111111111' } let(:status) { 404 }