diff --git a/lib/listen/thread.rb b/lib/listen/thread.rb index 2143580e..a1e6b3b6 100644 --- a/lib/listen/thread.rb +++ b/lib/listen/thread.rb @@ -24,7 +24,7 @@ def new(name, &block) def rescue_and_log(method_name, *args, caller_stack: nil) yield(*args) - rescue Exception => exception # rubocop:disable Lint/RescueException + rescue => exception _log_exception(exception, method_name, caller_stack: caller_stack) end diff --git a/spec/lib/listen/event/processor_spec.rb b/spec/lib/listen/event/processor_spec.rb index f3c6e6f4..e8105f3e 100644 --- a/spec/lib/listen/event/processor_spec.rb +++ b/spec/lib/listen/event/processor_spec.rb @@ -224,7 +224,7 @@ def status_for_time(time) end describe '_process_changes' do - context 'when it raises an exception derived from StandardError or not' do + context 'when it raises an exception derived from StandardError' do before do allow(event_queue).to receive(:empty?).and_return(true) allow(config).to receive(:callable?).and_return(true) @@ -232,12 +232,12 @@ def status_for_time(time) allow(config).to receive(:optimize_changes).with(anything).and_return(resulting_changes) expect(config).to receive(:call).and_raise(ArgumentError, "bang!") expect(config).to receive(:call).and_return(nil) - expect(config).to receive(:call).and_raise(ScriptError, "ruby typo!") + expect(config).to receive(:call).and_raise("error!") end it 'rescues and logs exception and continues' do expect(Listen.logger).to receive(:error).with(/Exception rescued in _process_changes:\nArgumentError: bang!/) - expect(Listen.logger).to receive(:error).with(/Exception rescued in _process_changes:\nScriptError: ruby typo!/) + expect(Listen.logger).to receive(:error).with(/Exception rescued in _process_changes:\nRuntimeError: error!/) expect(Listen.logger).to receive(:debug).with(/Callback \(exception\) took/) expect(Listen.logger).to receive(:debug).with(/Callback took/) expect(Listen.logger).to receive(:debug).with(/Callback \(exception\) took/) diff --git a/spec/lib/listen/thread_spec.rb b/spec/lib/listen/thread_spec.rb index a6966402..dc31f4f2 100644 --- a/spec/lib/listen/thread_spec.rb +++ b/spec/lib/listen/thread_spec.rb @@ -63,6 +63,32 @@ end end + class TestExceptionDerivedFromException < Exception; end # rubocop:disable Lint/InheritException + + context "when process exit/failure exception raised" do + [SystemExit, SystemStackError, NoMemoryError, SecurityError, TestExceptionDerivedFromException].each do |exception| + context exception.name do + let(:block) do + -> { raise exception, 'boom!' } + end + + it "does not rescue" do + expect(Thread).to receive(:new) do |&block| + expect do + block.call + end.to raise_exception(exception, 'boom!') + + thread = instance_double(Thread, "thread") + allow(thread).to receive(:name=).with(any_args) + thread + end + + subject + end + end + end + end + context "when nested exceptions raised" do let(:block) { raise_nested_exception_block } @@ -82,9 +108,10 @@ context 'when exception raised that is not derived from StandardError' do let(:block) { raise_script_error_block } - it "still rescues and logs" do - expect(Listen.logger).to receive(:error).with(/Exception rescued in listen-worker_thread:\nScriptError: ruby typo!/) - subject.join + it "raises out of the thread" do + expect do + subject.join + end.to raise_exception(ScriptError, "ruby typo!") end end end @@ -106,9 +133,10 @@ context 'when exception raised that is not derived from StandardError' do let(:block) { raise_script_error_block } - it 'still rescues and logs' do - expect(Listen.logger).to receive(:error).with(/Exception rescued in method:\nScriptError: ruby typo!/) - described_class.rescue_and_log("method", &block) + it "raises out of the thread" do + expect do + described_class.rescue_and_log("method", &raise_script_error_block) + end.to raise_exception(ScriptError, "ruby typo!") end end end