diff --git a/app/services/gpo_confirmation_uploader.rb b/app/services/gpo_confirmation_uploader.rb index 315c649a244..54422aba58c 100644 --- a/app/services/gpo_confirmation_uploader.rb +++ b/app/services/gpo_confirmation_uploader.rb @@ -43,8 +43,14 @@ def generate_export(confirmations) def upload_export(export) return unless FeatureManagement.gpo_upload_enabled? io = StringIO.new(export) - Net::SFTP.start(*sftp_config) do |sftp| - sftp.upload!(io, remote_path) + + with_retries( + max_tries: 5, + rescue: [Net::SFTP::Exception, Net::SSH::Exception], + ) do + Net::SFTP.start(*sftp_config) do |sftp| + sftp.upload!(io, remote_path) + end end end diff --git a/spec/services/gpo_confirmation_uploader_spec.rb b/spec/services/gpo_confirmation_uploader_spec.rb index 4612d1882fc..8b95c27fb22 100644 --- a/spec/services/gpo_confirmation_uploader_spec.rb +++ b/spec/services/gpo_confirmation_uploader_spec.rb @@ -71,6 +71,28 @@ subject end + + context 'when an SSH error occurs' do + it 'retries the upload' do + expect(Net::SFTP).to receive(:start).twice.with(*sftp_options).and_yield(sftp_connection) + expect(sftp_connection).to receive(:upload!).once.and_raise(Net::SSH::ConnectionTimeout) + expect(sftp_connection).to receive(:upload!).once + + subject + end + + it 'raises after 5 unsuccessful retries' do + expect(Net::SFTP).to receive(:start). + exactly(5).times. + with(*sftp_options). + and_yield(sftp_connection) + expect(sftp_connection).to receive(:upload!). + exactly(5).times. + and_raise(Net::SSH::ConnectionTimeout) + + expect { subject }.to raise_error(Net::SSH::ConnectionTimeout) + end + end end describe '#run' do