return/throw #3

dvv opened this Issue Oct 26, 2010 · 5 comments


None yet
5 participants

dvv commented Oct 26, 2010


Is it possible to teach .waterfall() take functions which simply return the result on success (instead of cb(null, result)) and throw an error (instead of cb(err)) on error condition? That way could be possible to extract the logic of actions to vanilla functions which could be both sync/async, thus making .waterfall() neutral to asynchronity. Also that could simplify exception handling, since either programmatic throw or real exception would be equivalent.

What do you think?



caolan commented Oct 26, 2010

I suppose it would be possible to support that in most cases. If the function throws then pass the error to the final callback, if it returns something other than undefined / null, then execute the next function and pass in that value.

The problem is that it then no-longer behaves in a way you'd just expect. Most node.js functions that accept a callback don't care what you return, and I don't want to stray too far from the normal node.js style. Also, what if you wanted to pass undefined as an argument to the next function?

I think trying to add this would complicate things, even though I understand why you might want it supported. For now, I would recommend just wrapping your sync function with one that accepts a callback... if you find you're doing that a lot I could create a shorthand for it, something like async.wrap(fn)

dvv commented Oct 26, 2010

I see. Of course I didn't mean to force the changes, just maybe a special .waterfall() copy-paste. The most I do care is of exception handling that might occure within callbacks. Such exceptions don't get caught by enclosing try/catch since when moved to callback the executing context is gone out of scope guarded by try/catch.

I might be wrong or miss something, but how to reliably instruct .waterfall() to not leak any unhandled exception out? If each waterfall "step" returned or throwed, internal waterfall logic could make use of try/catch and feed caught exceptions right to the final callback, thus fulfilling the task. Thoughts?


thejh commented Feb 19, 2011

How about checking a function property? Something like if (func.sync === true)? And having a helper function async.markSync(func) that can set the flag?
function markSync(func) {
func.sync = true;
return func;

Actually, you can easily implement it by yourself, like

async.toAsync = function (syncFunction) {
    return function() {
        var callback = pop(arguments);
        try {
            callback(false, syncFunction.apply(null, arguments));
        } catch(err) {

and then use it like this:

    async.toAsync(function() { return 2; }),
    async.toAsync(function(x) { return 1/x; }),
], callback);

brianmaissy commented Feb 20, 2013

I think this should be closed.

caolan closed this Mar 2, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment