fix(api_entreprise): better handle api entreprise errors
This commit is contained in:
parent
c8f69283cc
commit
d13c475170
7 changed files with 48 additions and 14 deletions
|
@ -188,8 +188,8 @@ module Users
|
|||
sanitized_siret = siret_model.siret
|
||||
etablissement = begin
|
||||
APIEntrepriseService.create_etablissement(@dossier, sanitized_siret, current_user.id)
|
||||
rescue => error
|
||||
if error.is_a?(APIEntreprise::API::Error::ServiceUnavailable) || (error.try(:network_error?) && !APIEntrepriseService.api_insee_up?)
|
||||
rescue APIEntreprise::API::Error, APIEntrepriseToken::TokenError => error
|
||||
if APIEntrepriseService.service_unavailable_error?(error, target: :insee)
|
||||
# TODO: notify ops
|
||||
APIEntrepriseService.create_etablissement_as_degraded_mode(@dossier, sanitized_siret, current_user.id)
|
||||
else
|
||||
|
|
8
app/jobs/api_entreprise/etablissement_job.rb
Normal file
8
app/jobs/api_entreprise/etablissement_job.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class APIEntreprise::EtablissementJob < APIEntreprise::Job
|
||||
def perform(etablissement_id, procedure_id)
|
||||
find_etablissement(etablissement_id)
|
||||
APIEntrepriseService.update_etablissement_from_degraded_mode(etablissement, procedure_id)
|
||||
end
|
||||
end
|
|
@ -1,5 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# TODO: remove this job in a few days once all failed etablissements are queued as separate jobs
|
||||
class Cron::BackfillSiretDegradedModeJob < Cron::CronJob
|
||||
self.schedule_expression = "every 2 hour"
|
||||
|
||||
|
|
|
@ -138,10 +138,10 @@ class APIEntreprise::API
|
|||
end
|
||||
end
|
||||
|
||||
SERVICE_UNAVAILABLE_ERRORS = ["01000", "01001", "01002", "02002", "03002", "28002", "29002", "31002", "34002"]
|
||||
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", "02002", "03002"].include?(_1[:code]) }
|
||||
parse_response_errors(response).any? { _1.is_a?(Hash) && _1[:code]&.in?(SERVICE_UNAVAILABLE_ERRORS) }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -12,10 +12,14 @@ module RNAChampAssociationFetchableConcern
|
|||
return clear_association!(:invalid) unless valid_champ_value?
|
||||
return clear_association!(:not_found) if (data = APIEntreprise::RNAAdapter.new(rna, procedure_id).to_params).blank?
|
||||
|
||||
update!(data: data, value_json: APIGeoService.parse_rna_address(data['adresse']))
|
||||
rescue APIEntreprise::API::Error => error
|
||||
error_key = :network_error if error.try(:network_error?) && !APIEntrepriseService.api_djepva_up?
|
||||
clear_association!(error_key)
|
||||
update!(data:, value_json: APIGeoService.parse_rna_address(data['adresse']))
|
||||
rescue APIEntreprise::API::Error, APIEntrepriseToken::TokenError => error
|
||||
if APIEntrepriseService.service_unavailable_error?(error, target: :djepva)
|
||||
clear_association!(:network_error)
|
||||
else
|
||||
Sentry.capture_exception(error, extra: { dossier_id:, rna: })
|
||||
clear_association!(nil)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -11,16 +11,16 @@ module SiretChampEtablissementFetchableConcern
|
|||
return clear_etablissement!(:invalid_checksum) if invalid_because?(siret, :checksum) # i18n-tasks-use t('errors.messages.invalid_siret_checksum')
|
||||
return clear_etablissement!(:not_found) unless (etablissement = APIEntrepriseService.create_etablissement(self, siret, user&.id)) # i18n-tasks-use t('errors.messages.siret_not_found')
|
||||
|
||||
update!(etablissement: etablissement, value_json: APIGeoService.parse_etablissement_address(etablissement))
|
||||
rescue => error
|
||||
if error.try(:network_error?) && !APIEntrepriseService.api_insee_up?
|
||||
update!(etablissement:)
|
||||
rescue APIEntreprise::API::Error, APIEntrepriseToken::TokenError => error
|
||||
if APIEntrepriseService.service_unavailable_error?(error, target: :insee)
|
||||
update!(
|
||||
etablissement: APIEntrepriseService.create_etablissement_as_degraded_mode(self, siret, user.id)
|
||||
)
|
||||
@etablissement_fetch_error_key = :api_entreprise_down
|
||||
false
|
||||
else
|
||||
Sentry.capture_exception(error, extra: { dossier_id: dossier_id, siret: siret })
|
||||
Sentry.capture_exception(error, extra: { dossier_id:, siret: })
|
||||
clear_etablissement!(:network_error) # i18n-tasks-use t('errors.messages.siret_network_error')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,6 +23,10 @@ class APIEntrepriseService
|
|||
etablissement = dossier_or_champ.build_etablissement(etablissement_params)
|
||||
etablissement.save!
|
||||
|
||||
if dossier_or_champ.is_a?(Champ)
|
||||
dossier_or_champ.update!(value_json: APIGeoService.parse_etablissement_address(etablissement))
|
||||
end
|
||||
|
||||
perform_later_fetch_jobs(etablissement, procedure_id, user_id)
|
||||
|
||||
etablissement
|
||||
|
@ -45,15 +49,25 @@ class APIEntrepriseService
|
|||
return nil if etablissement_params.empty?
|
||||
|
||||
etablissement.update!(etablissement_params)
|
||||
|
||||
if etablissement.champ.present?
|
||||
etablissement.champ.update!(value_json: APIGeoService.parse_etablissement_address(etablissement))
|
||||
end
|
||||
|
||||
etablissement
|
||||
end
|
||||
|
||||
def perform_later_fetch_jobs(etablissement, procedure_id, user_id, wait: nil)
|
||||
[
|
||||
jobs = [
|
||||
APIEntreprise::EntrepriseJob, APIEntreprise::ExtraitKbisJob, APIEntreprise::TvaJob,
|
||||
APIEntreprise::AssociationJob, APIEntreprise::ExercicesJob,
|
||||
APIEntreprise::EffectifsJob, APIEntreprise::EffectifsAnnuelsJob, APIEntreprise::AttestationSocialeJob,
|
||||
APIEntreprise::BilansBdfJob
|
||||
].each do |job|
|
||||
]
|
||||
if etablissement.as_degraded_mode?
|
||||
jobs << APIEntreprise::EtablissementJob
|
||||
end
|
||||
jobs.each do |job|
|
||||
job.set(wait:).perform_later(etablissement.id, procedure_id)
|
||||
end
|
||||
|
||||
|
@ -69,6 +83,13 @@ class APIEntrepriseService
|
|||
api_up?("https://entreprise.api.gouv.fr/ping/djepva/api-association")
|
||||
end
|
||||
|
||||
def service_unavailable_error?(error, target:)
|
||||
return false if !error.try(:network_error?)
|
||||
return true if target == :insee && !APIEntrepriseService.api_insee_up?
|
||||
return true if target == :djepva && !APIEntrepriseService.api_djepva_up?
|
||||
error.is_a?(APIEntreprise::API::Error::ServiceUnavailable)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def api_up?(url)
|
||||
|
|
Loading…
Reference in a new issue