Philosophy of Throwing Errors

26 views
Skip to first unread message

Nate Schmolze

unread,
Dec 20, 2015, 9:59:18 PM12/20/15
to bluebird
Hey all,

I'm developing a promise implementation that uses bluebird internally (basically promises with plugins), and I'm wavering on deciding how errors should be handled when they are encountered synchronously; I could use some advice from more experienced promisifiers.  Two examples:

reach.mysql("SELECT * FROM nonexistent_table").each(function(row) {
   
// process row
})
.then(...);


reach
.mysql(null).each(function(row) {
   
// process row
})
.then(...);

In the first example, user code is trying to select from a nonexistent mysql table.  This is an error that will be thrown asynchronously, no problem - catch it in a .catch statement.

In the second example however, user code is providing bad arguments to the .mysql function - the query string is null.  In this case, the code recognizes the problem and can throw immediately.  My question is, should bad arguments to a method (or other synchronous errors) cause a rejected promise to return, or should they throw immediately?  I saw the following tidbit on the main bluebird site, which seems to suggest that promise-returning functions should never throw:

To make sure a function that returns a promise is following the implicit but critically important contract of promises, you can start a function with new Promise if you cannot start a chain immediately:

It got me thinking.  When I tested bluebird functions, I got mixed results.  Promise.all returns a rejected promise for empty arguments (presumably it does a .resolve() because it needs to check for bad arguments asynchronously), whereas constructing a new Promise throws synchronously (new Promise()).  There's of course nothing on the A+ specification handling these things (IIRC), but I thought people on this group might have a good idea which direction to go.  Some situations might be difficult to return a rejected promise, because certain static methods won't normally return a promise, and a throw would be more natural.  But for the average, chainable instance method, should synchronous errors be handled asynchronously, or thrown?

Thanks for any thoughts!
~ Nate

Reply all
Reply to author
Forward
0 new messages