samstokes/deferrable_gratification — Issue #5: Join that does not swallow failures
Author: ept
Created: 2012-02-06 04:37:12+00:00
State: open

I spent a while trying to track down a bug that was masked by `DG::join_successes`. What happened was something like this:

```ruby
def operation(param)
something_async(param).transform do |value|
call_some_method_that_does_not_exist! # raises NameError
end
end

def one_two_three
DG::join_successes operation('one'), operation('two'), operation('three')
end
```

That NameError caused each `operation` to fail, but because `join_successes` discarded the failures, `one_two_three` succeeded. I had error logging on an errback, but it never got logged, which left me scratching my head for a while.

In a context where the constituent deferrables are expected to succeed, it would be nicer for the join combinator to immediately escalate any failure. Something like this:

```ruby
# If any of the joined deferrables fails, fails immediately with that failure's error.
# Otherwise waits for all deferrables to succeed, and succeeds with an array of success results.
class JoinCarefully < DeferrableGratification::Combinators::Join
private
def done?
failures.length > 0 || all_completed?
end

def finish
if failures.empty?
succeed(successes)
else
fail(failures.first)
end
end
end
```