Skip to content

Commit

Permalink
Fix error handling in edge promises
Browse files Browse the repository at this point in the history
* Now properly handles errors raised within deeply nested futures.
* `value!` now properly works with `rejected_future`

Fixes ruby-concurrency#659
  • Loading branch information
David Abdemoulaie committed Jun 6, 2017
1 parent 041c1d1 commit 3b76f7c
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 3 deletions.
4 changes: 2 additions & 2 deletions lib/concurrent/edge/promises.rb
Expand Up @@ -982,12 +982,12 @@ def value!(timeout = nil)
# @return [Exception]
def exception(*args)
raise Concurrent::Error, 'it is not rejected' unless rejected?
reason = Array(internal_state.reason).compact
reason = Array(internal_state.reason).flatten.compact
if reason.size > 1
Concurrent::MultipleErrors.new reason
else
ex = reason[0].exception(*args)
ex.set_backtrace ex.backtrace + caller
ex.set_backtrace Array(ex.backtrace) + caller
ex
end
end
Expand Down
14 changes: 13 additions & 1 deletion spec/concurrent/edge/promises_spec.rb
Expand Up @@ -220,9 +220,14 @@ def behaves_as_delay(delay, value)
let(:a_future) { future { raise 'error' } }

it 'raises a concurrent error' do
expect { zip(a_future).value! }.to raise_error(StandardError)
expect { zip(a_future).value! }.to raise_error(StandardError, 'error')
end

context 'when deeply nested' do
it 'raises the original error' do
expect { zip(zip(a_future)).value! }.to raise_error(StandardError, 'error')
end
end
end
end

Expand All @@ -242,6 +247,13 @@ def behaves_as_delay(delay, value)
end
end

describe '.rejected_future' do
it 'raises the correct error when passed an unraised error' do
f = rejected_future(StandardError.new('boom'))
expect { f.value! }.to raise_error(StandardError, 'boom')
end
end

describe 'Future' do
it 'has sync and async callbacks' do
callbacks_tester = ->(event_or_future) do
Expand Down

0 comments on commit 3b76f7c

Please sign in to comment.