I really like error-propagation via Promises. Under the hood, I throw for sync functions and use promises for async functions, but nearly all higher functions use Promises and I really recommend making strictly sure that all errors which might happen are propagated to the highest level possible.
By the way, I do not use wrappers. I just use the functions and methods as documented, but when I call them, I try to bring them into my scheme.
Examples:
// Promises
var defer = require('promise-defer');
/**
* Does something
*
* @return Promise
* int on success
* error on fail
*/
function foo() {
var d = defer();
// Yes, in this case you could just return the result directly, but for clarification I will leave it like this
doAsync().then(d.resolve, d.reject);
return d.promise;
}
// Error Callback
var defer = require('promise-defer');
/**
* Does something
*
* @return Promise
* int on success
* error on fail
*/
function foo() {
var d = defer();
doAsync((err, result) => {
if (err) {
d.reject(new Error(err));
return;
}
d.resolve(result);
});
return d.promise;
}
// Throw
var defer = require('promise-defer');
/**
* Does something sync
*
* @throws string
*/
function doSync() {
throw 'No catnip :(';
}
/**
* Does something
*
* @return Promise
* int on success
* error on fail
*/
function foo() {
var d = defer();
try {
d.resolve(doSync());
}
catch(err) {
// err is already an Error Object
d.reject(err);
}
return d.promise;
}