Merge pull request #10931 from tchak/better-handle-api-entreprise-jobs
fix(api_entreprise): better handle api entreprise errors
This commit is contained in:
commit
ad7458a12f
7 changed files with 48 additions and 14 deletions
|
@ -188,8 +188,8 @@ module Users
|
||||||
sanitized_siret = siret_model.siret
|
sanitized_siret = siret_model.siret
|
||||||
etablissement = begin
|
etablissement = begin
|
||||||
APIEntrepriseService.create_etablissement(@dossier, sanitized_siret, current_user.id)
|
APIEntrepriseService.create_etablissement(@dossier, sanitized_siret, current_user.id)
|
||||||
rescue => error
|
rescue APIEntreprise::API::Error, APIEntrepriseToken::TokenError => error
|
||||||
if error.is_a?(APIEntreprise::API::Error::ServiceUnavailable) || (error.try(:network_error?) && !APIEntrepriseService.api_insee_up?)
|
if APIEntrepriseService.service_unavailable_error?(error, target: :insee)
|
||||||
# TODO: notify ops
|
# TODO: notify ops
|
||||||
APIEntrepriseService.create_etablissement_as_degraded_mode(@dossier, sanitized_siret, current_user.id)
|
APIEntrepriseService.create_etablissement_as_degraded_mode(@dossier, sanitized_siret, current_user.id)
|
||||||
else
|
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
|
# 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
|
class Cron::BackfillSiretDegradedModeJob < Cron::CronJob
|
||||||
self.schedule_expression = "every 2 hour"
|
self.schedule_expression = "every 2 hour"
|
||||||
|
|
||||||
|
|
|
@ -138,10 +138,10 @@ class APIEntreprise::API
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
SERVICE_UNAVAILABLE_ERRORS = ["01000", "01001", "01002", "02002", "03002", "28002", "29002", "31002", "34002"]
|
||||||
def service_unavailable?(response)
|
def service_unavailable?(response)
|
||||||
return true if response.code == 503
|
|
||||||
if response.code == 502 || response.code == 504
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,14 @@ module RNAChampAssociationFetchableConcern
|
||||||
return clear_association!(:invalid) unless valid_champ_value?
|
return clear_association!(:invalid) unless valid_champ_value?
|
||||||
return clear_association!(:not_found) if (data = APIEntreprise::RNAAdapter.new(rna, procedure_id).to_params).blank?
|
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']))
|
update!(data:, value_json: APIGeoService.parse_rna_address(data['adresse']))
|
||||||
rescue APIEntreprise::API::Error => error
|
rescue APIEntreprise::API::Error, APIEntrepriseToken::TokenError => error
|
||||||
error_key = :network_error if error.try(:network_error?) && !APIEntrepriseService.api_djepva_up?
|
if APIEntrepriseService.service_unavailable_error?(error, target: :djepva)
|
||||||
clear_association!(error_key)
|
clear_association!(:network_error)
|
||||||
|
else
|
||||||
|
Sentry.capture_exception(error, extra: { dossier_id:, rna: })
|
||||||
|
clear_association!(nil)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
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!(: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')
|
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))
|
update!(etablissement:)
|
||||||
rescue => error
|
rescue APIEntreprise::API::Error, APIEntrepriseToken::TokenError => error
|
||||||
if error.try(:network_error?) && !APIEntrepriseService.api_insee_up?
|
if APIEntrepriseService.service_unavailable_error?(error, target: :insee)
|
||||||
update!(
|
update!(
|
||||||
etablissement: APIEntrepriseService.create_etablissement_as_degraded_mode(self, siret, user.id)
|
etablissement: APIEntrepriseService.create_etablissement_as_degraded_mode(self, siret, user.id)
|
||||||
)
|
)
|
||||||
@etablissement_fetch_error_key = :api_entreprise_down
|
@etablissement_fetch_error_key = :api_entreprise_down
|
||||||
false
|
false
|
||||||
else
|
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')
|
clear_etablissement!(:network_error) # i18n-tasks-use t('errors.messages.siret_network_error')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,6 +23,10 @@ class APIEntrepriseService
|
||||||
etablissement = dossier_or_champ.build_etablissement(etablissement_params)
|
etablissement = dossier_or_champ.build_etablissement(etablissement_params)
|
||||||
etablissement.save!
|
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)
|
perform_later_fetch_jobs(etablissement, procedure_id, user_id)
|
||||||
|
|
||||||
etablissement
|
etablissement
|
||||||
|
@ -45,15 +49,25 @@ class APIEntrepriseService
|
||||||
return nil if etablissement_params.empty?
|
return nil if etablissement_params.empty?
|
||||||
|
|
||||||
etablissement.update!(etablissement_params)
|
etablissement.update!(etablissement_params)
|
||||||
|
|
||||||
|
if etablissement.champ.present?
|
||||||
|
etablissement.champ.update!(value_json: APIGeoService.parse_etablissement_address(etablissement))
|
||||||
|
end
|
||||||
|
|
||||||
|
etablissement
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform_later_fetch_jobs(etablissement, procedure_id, user_id, wait: nil)
|
def perform_later_fetch_jobs(etablissement, procedure_id, user_id, wait: nil)
|
||||||
[
|
jobs = [
|
||||||
APIEntreprise::EntrepriseJob, APIEntreprise::ExtraitKbisJob, APIEntreprise::TvaJob,
|
APIEntreprise::EntrepriseJob, APIEntreprise::ExtraitKbisJob, APIEntreprise::TvaJob,
|
||||||
APIEntreprise::AssociationJob, APIEntreprise::ExercicesJob,
|
APIEntreprise::AssociationJob, APIEntreprise::ExercicesJob,
|
||||||
APIEntreprise::EffectifsJob, APIEntreprise::EffectifsAnnuelsJob, APIEntreprise::AttestationSocialeJob,
|
APIEntreprise::EffectifsJob, APIEntreprise::EffectifsAnnuelsJob, APIEntreprise::AttestationSocialeJob,
|
||||||
APIEntreprise::BilansBdfJob
|
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)
|
job.set(wait:).perform_later(etablissement.id, procedure_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -69,6 +83,13 @@ class APIEntrepriseService
|
||||||
api_up?("https://entreprise.api.gouv.fr/ping/djepva/api-association")
|
api_up?("https://entreprise.api.gouv.fr/ping/djepva/api-association")
|
||||||
end
|
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
|
private
|
||||||
|
|
||||||
def api_up?(url)
|
def api_up?(url)
|
||||||
|
|
Loading…
Reference in a new issue