diff --git a/app/jobs/batch_operation_process_one_job.rb b/app/jobs/batch_operation_process_one_job.rb index 10f3f2547..32870ac57 100644 --- a/app/jobs/batch_operation_process_one_job.rb +++ b/app/jobs/batch_operation_process_one_job.rb @@ -1,16 +1,20 @@ class BatchOperationProcessOneJob < ApplicationJob - retry_on StandardError, attempts: 1 + retry_on StandardError, attempts: 1 # default 5, for now no retryable behavior def perform(batch_operation, dossier) dossier = batch_operation.dossiers_safe_scope.find(dossier.id) begin - batch_operation.process_one(dossier) - batch_operation.track_processed_dossier(true, dossier) + ActiveRecord::Base.transaction do + batch_operation.process_one(dossier) + batch_operation.track_processed_dossier(true, dossier) + end rescue => error - batch_operation.track_processed_dossier(false, dossier) + ActiveRecord::Base.transaction do + batch_operation.track_processed_dossier(false, dossier) + end raise error end rescue ActiveRecord::RecordNotFound - dossier.update(batch_operation_id: nil) + dossier.update_column(:batch_operation_id, nil) end end diff --git a/spec/jobs/batch_operation_process_one_job_spec.rb b/spec/jobs/batch_operation_process_one_job_spec.rb index bc76cf16d..568576f6c 100644 --- a/spec/jobs/batch_operation_process_one_job_spec.rb +++ b/spec/jobs/batch_operation_process_one_job_spec.rb @@ -65,6 +65,35 @@ describe BatchOperationProcessOneJob, type: :job do .from(nil) .to('motivation') end + + context 'when it raises a ActiveRecord::StaleObjectError' do + before { allow_any_instance_of(Dossier).to receive(:after_accepter).and_raise(ActiveRecord::StaleObjectError) } + + it 'with invalid dossier (ex: ActiveRecord::StaleObjectError), unlink dossier/batch_operation with update_column' do + scope = double + expect(scope).to receive(:find).with(dossier_job.id).and_return(dossier_job) + expect_any_instance_of(BatchOperation).to receive(:dossiers_safe_scope).and_return(scope) + dossier_job.errors.add('KC') + + expect do + begin + subject.perform_now + rescue ActiveRecord::StaleObjectError + # noop, juste want to catch existing error but not others + end + end.to change { dossier_job.reload.batch_operation }.from(batch_operation).to(nil) + end + + it 'does not change dossier state' do + expect do + begin + subject.perform_now + rescue ActiveRecord::StaleObjectError + # noop, juste want to catch existing error but not others + end + end.not_to change { dossier_job.reload.accepte? } + end + end end context 'when operation is "accepter" with justificatif' do