From 0da823908515ab90de1c188ba01f99873fc8b1aa Mon Sep 17 00:00:00 2001 From: Michael Grosser Date: Wed, 1 Apr 2026 18:27:25 -0700 Subject: [PATCH] dump undumpable exceptions without cause if that fixes the issue --- lib/parallel.rb | 11 ++++++++++ .../parallel_break_with_undumpable_cause.rb | 20 +++++++++++++++++++ spec/parallel_spec.rb | 5 +++++ 3 files changed, 36 insertions(+) create mode 100644 spec/cases/parallel_break_with_undumpable_cause.rb diff --git a/lib/parallel.rb b/lib/parallel.rb index d0c3f37..6c79b04 100644 --- a/lib/parallel.rb +++ b/lib/parallel.rb @@ -15,6 +15,17 @@ def initialize(value = nil) super() @value = value end + + # marshal_dump that is used for ruby exceptions + # avoid dumping the cause since nobody needs that and it can include undumpable exceptions + def _dump(_depth) + Marshal.dump(@value) + end + + # marshal_load that is used for ruby exceptions + def self._load(data) + new(Marshal.load(data)) + end end class Kill < Break diff --git a/spec/cases/parallel_break_with_undumpable_cause.rb b/spec/cases/parallel_break_with_undumpable_cause.rb new file mode 100644 index 0000000..e91f521 --- /dev/null +++ b/spec/cases/parallel_break_with_undumpable_cause.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true +require './spec/cases/helper' + +class UndumpableCauseError < StandardError + def initialize + super("bad") + @binding = binding # can't be dumped when it is the cause + end +end + +begin + x = Parallel.in_processes(2) do + raise UndumpableCauseError + rescue StandardError + raise Parallel::Break, "hello" + end + puts "Result: #{x}" +rescue StandardError => e + puts "Error: #{e.class}: #{e.message}" +end diff --git a/spec/parallel_spec.rb b/spec/parallel_spec.rb index 8fe1b0a..445264d 100644 --- a/spec/parallel_spec.rb +++ b/spec/parallel_spec.rb @@ -180,6 +180,11 @@ def cpus out.should == "NOTHING WAS RAISED" end + it "can handle Break with an undumpable cause" do + out = ruby("spec/cases/parallel_break_with_undumpable_cause.rb").strip + out.should == "Result: hello" + end + it 'can handle to high fork rate' do next if RbConfig::CONFIG["target_os"].include?("darwin1") # kills macs for some reason ruby("spec/cases/parallel_high_fork_rate.rb").should == 'OK'