aim-error-at
Build or modify an Error so that it is aimed towards the specified exit.
Useful in synchronous machines, big switch statements, and loops inside of try/catch blocks. Also useful outside of the context of machines for assigning useful error codes to the errors sent back by ANY JavaScript function.

Installation 
$ npm install aim-error-at --save --save-exact
Usage
var aimErrorAt = require('aim-error-at');
Modify existing error
var err = aimErrorAt('notCandy', new Error('Hello'));
Build new error from a message
var err = aimErrorAt('notCandy', 'Hello');
Build anonymous error
var err = aimErrorAt('notCandy');
Examples
A few examples of using this module to handle errors in different scenarios.
In a synchronous scenario:
try {
_.each(candies, function (thisCandy) {
throw aimErrorAt('notCandy', 'That\'s not a proper piece of candy!');
});
}
catch (e) {
if (e.exit && e.exit === 'notCandy') {
e.totalNumCandies = candies.length;
throw e;
}
else {
throw e;
}
}
return;
In an asynchronous scenario:
async.each(candies, function (thisCandy, next) {
return next( aimErrorAt('notCandy', 'That\'s not a proper piece of candy!') );
}, function afterwards(err) {
if (err.exit && err.exit === 'notCandy') {
console.warn('uh oh');
err.totalNumCandies = candies.length;
return cb(err);
}
else if (err) {
return cb(err);
}
return cb();
});
In a machine definition
module.exports = {
exits: {
success: {
description: 'All potential candies have been confirmed as such.'
},
notCandy: {
description: 'One or more of the potential candies is NOT CANDY.'
}
},
fn: function (inputs, exits) {
var aimErrorAt = require('aim-error-at');
try {
inputs.potentialCandies.forEach(function (item){
if (item !== 'candy') {
throw aimErrorAt('notCandy');
}
});
}
catch (e) {
if (e.exit && e.exit === 'notCandy') {
return exits.notCandy({ totalNumCandies: inputs.potentialCandies.length });
}
else {
return exits(e);
}
}
return exits.success();
}
};
In a Sails.js action:
if (!_.isArray(req.param('candies'))) {
return res.badRequest('`candies` should be provided as a JSON-encoded array.');
}
async.each(req.param('candies'), function (thisCandy, next) {
return next( aimErrorAt('notCandy', 'That\'s not a proper piece of candy!') );
}, function afterwards(err) {
if (err.exit && err.exit === 'notCandy') {
res.status(401);
return res.json({ totalNumCandies: candies.length });
}
else if (err) {
return res.serverError(err);
}
return res.ok();
});
Learn more about the project and our goals at http://node-machine.org/implementing/FAQ or check out the project newsgroup.
License
MIT © 2016 Mike McNeil and contributors