README
Storm Drain
Automation for bubbling asynchronous JavaScript errors up the call chain.
How it works
Let's say we have a little function that registers users:
registerUser (email, done) ->
createUser email, (err, user) ->
if err then return done err
activateUser user (err) ->
if err then return done err
sendWelcomeEmail email, done
StormDrain allows to dry up this code into:
drain = require 'storm-drain'
registerUser (email, done) ->
D = drain to: done
createUser email, D (err, user) ->
activateUser user, D (err) ->
sendWelcomeEmail email, done
Calling drain
with the return function for this code block (done
in this example)
returns a storm drain instance that drains to this function.
This instance (named D
for "drain") is then used to wrap the asynchronous
continuation functions (callbacks).
Without errors, D
is completely transparent and
simply calls the wrapped callback.
If D
receives an error, it calls the previously registered drain (done
)
with that error, and skips executing the wrapped callback.
Inline usage
If you use StormDrain only rarely, you can provide the callback to drain to directly when wrapping continuation functions, thereby saving the dedicated setup step:
S = require 'storm-drain'
registerUser (email, done) ->
createUser email, S done, (err, user) ->
activateUser user, S done, (err) ->
sendWelcomeEmail email, done
Convention over Configuration
For maximum convenience and DRYness, StormDrain also provides a convention that allows you to bypass all manual configuration efforts altogether. It is a little invasive, so you have to manually enable it, once per application:
# in your application setup
require('storm-drain').convention()
# in any file
registerUser (email, @done) ->
createUser email, @S (err, user) =>
activateUser user, @S (err) =>
sendWelcomeEmail email, done
In this mode, StormDrain adds a function S
to the Object prototype.
This function calls this.done
if it encounters an error.
Notice how you need to assign done
to the this
object, make sure that
this
has the same value in all nested callbacks, and call this.S
instead of S
to make this work.
The details of the behavior, like name of the global function and name of the return function to be called, can of course be configured:
require('stormDrain').convention globalName: 'SD', returnFunctionName: 'cb'
Related work
- node-okay: Comparable functionality, StormDrain provides more flexible ways of being used.
- nitroglycerin: Instead of bubbling errors up the call chain, the wrappers provided by this library always throw exceptions when errors occur. This makes test scripts or command-line apps even easier to write than with this library.
Development
See the developer documentation