deferrable_gratification
deferrable_gratification copied to clipboard
Join that does not swallow failures
I spent a while trying to track down a bug that was masked by DG::join_successes
. What happened was something like this:
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:
# 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