From 66ff3248e7f529d3b7481fdd7c5d1d7e3c2ae547 Mon Sep 17 00:00:00 2001 From: Phillip Davis Date: Mon, 25 May 2026 16:35:29 -0400 Subject: [PATCH] fix: don't explode when one port fails --- lib/port_repo.rb | 18 +++++++++------- test/test_port_repo.rb | 49 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/lib/port_repo.rb b/lib/port_repo.rb index af63679c4c2cc8a26c8258582f2bc3e44730c1e5..54392ae4a06c11d48b27bc8e3ad63ef994785112 100644 --- a/lib/port_repo.rb +++ b/lib/port_repo.rb @@ -134,13 +134,15 @@ class PortRepo protected def tick(port) - @step_repo.find(port).then { |step| - @output.info(port.id, :class, step.class) - if @dry_run - @output.info("DRY", :dry, "Not taking action") - else - step.perform_next_step - end - } + EMPromise.resolve(nil).then { + @step_repo.find(port).then { |step| + @output.info(port.id, :class, step.class) + if @dry_run + @output.info("DRY", :dry, "Not taking action") + else + step.perform_next_step + end + } + }.catch { |e| @output.error(port.id, :catch, e) } end end diff --git a/test/test_port_repo.rb b/test/test_port_repo.rb index cba8a047051b23c9218d56f3b36a9b8c73a1d106..4c9a840062790f2f95512272502c3f096d5c5aef 100644 --- a/test/test_port_repo.rb +++ b/test/test_port_repo.rb @@ -58,6 +58,55 @@ class PortRepoDbTest < Minitest::Test em :test_list_empty_when_no_rows end +class PortRepoTickTest < Minitest::Test + def setup + @expected_output = Minitest::Mock.new + @output = MockOutputs.new(@expected_output) + end + + def test_process_continues_after_individual_port_error + error = RuntimeError.new("port exploded") + + failing_port = PortRepo::Fake::FakePort.new( + "T02", "COMPLETE", DateTime.now, DateTime.now, + "0001", "2223334444", "testroute" + ) + ok_port = PortRepo::Fake::FakePort.new( + "T01", "SUBMITTED", nil, DateTime.now - 1, + "ignored", "9998887777", "testroute" + ) + + failing_step = Minitest::Mock.new( + PortingStepRepo::Frozen.new(failing_port, output: @output) + ) + failing_step.expect(:perform_next_step, EMPromise.reject(error)) + + ok_step = Minitest::Mock.new( + PortingStepRepo::Frozen.new(ok_port, output: @output) + ) + ok_step.expect(:perform_next_step, EMPromise.resolve(nil)) + + step_repo = Minitest::Mock.new(PortingStepRepo.new(output: @output)) + step_repo.expect(:find, EMPromise.resolve(failing_step), [failing_port]) + step_repo.expect(:find, EMPromise.resolve(ok_step), [ok_port]) + + @expected_output.expect(:error, nil, [failing_port.id, :catch, error]) + @expected_output.expect( + :info, nil, [failing_port.id, :class, failing_step.class] + ) + @expected_output.expect(:info, nil, [ok_port.id, :class, ok_step.class]) + + repo = PortRepo::Fake.new(@output) + repo.instance_variable_set(:@step_repo, step_repo) + repo.stub(:list, EMPromise.resolve([failing_port, ok_port])) do + repo.process.sync + end + + @output.verify + end + em :test_process_continues_after_individual_port_error +end + class PortRepoBandwidthTest < Minitest::Test def setup @output = FullManual.new