Outcome.js is a simple flow-control library which wraps your .callback(err, result)
functions.
Motiviation
- Write less code for handling errors.
- Easier to maintain.
- Keep error handling code separate.
Basic Example
Here's the traditional method of handling errors:
var fs = require('fs');
function doSomething(path, callback) {
fs.realpath(path, onRealPath);
function onRealPath(err, path) {
if(err) return callback(err);
fs.lstat(path, onStat);
}
function onStat(err, stats) {
if(err) return callback(err);
callback(err, stats);
}
}
doSomething('/path/to/something', function(err, result) {
if(err) {
return;
}
})
The outcome.js way:
var fs = require('fs'),
outcome = require('outcome');
function doSomething(path, callback) {
var on = outcome.error(callback);
fs.realpath(path, on.success(onRealPath));
function onRealPath(path) {
fs.lstat(path, on.success(onStat));
}
function onStat(stats) {
callback(null, stats);
}
}
var on = outcome.error(function(error) {
}));
doSomething('/path/to/something', on.success(function(response) {
}));
API
outcome(listeners)
listeners
- Object of listeners you want to attach to outcome.
var onResult = outcome({
error: function(error) {
},
success: function(result, thirdParam) {
},
callback: function(err, result, thirdParam) {
}
})
As shown in the example above, you can also wrap-around an existing callback:
var onResult = outcome.error(function(error) {
}).
success(function(result, thirdParam) {
}).
callback(function(error, result, thirdParam) {
});
By default, any unhandled errors are thrown. To get around this, you'll need to listen for an unhandledError
:
outcome.on('unhandledError', function(error) {
});
fs.stat('s'+__filename, outcome.success(function() {
});
.callback()
Called when on error/success. Same as function(err, data) { }
Here's a redundant example:
fs.stat(__filename, outcome.error(function(err) {
}).success(function(data) {
}.callback(function(err, result) {
}));
.success(fn)
Called on Success.
var onOutcome = outcome.success(function(data, anotherParam, andAnotherParam) {
});
onOutcome(null, "success!", "more data!", "more results..");
.error(fn)
Called on error.
var onOutcome = outcome.error(function(err) {
});
onOutcome(new Error("something went wrong..."));
.handle(fn)
Custom response handler
outcome.handle(function(response) {
if(response.errors) this.error(response);
if(response.data) this.success(response);
});
CoffeeScript Example
outcome = require "outcome"
doSomething(path, callback) ->
on = outcome.error callback
# first get the realpath
fs.realpath path, on.success onRealPath
# on real path, get stats
onRealPath(path) -> fs.lstat path, on.success onStat
# on stat, finish
onStat(stats) -> callback null, stats
# call do something
doSomething '/path/to/something', outcome
success: (statis) ->
# do something
error: (error) ->
# do something else
Note
Calling .error()
, .success()
, .callback()
generates a new function which copies the previous listeners.
Checkout fs-test in the examples folder.