How to refactor a promise catch that uses the same function, but also a variable in the calling one?
Just create a function and pass the res
object as an argument and return a function.
function makeErrorCatcher(res) { return function catchesError(err) { return res.json({ success: false }); }}router.get('/', function (req, res) { return somePromise .then(function doesSomething(someVariable) { doSomething; }) .catch(makeErrorCatcher(res));});
You can decorate .get
to pass to have a default catch handler. (Assuming you're not interested in a custom router):
Object.keys(router).forEach(function(key){ // for each method router[key+"P"] = function(path, fn){ // create a decorated alt router[key].call(router, function(req, res, next){ // delegate var that = this, args = arguments; return Promise.try(function(){ // wrap to make throw safe return fn.apply(that, args); // delegation }).catch(function catchesError(err){ // LOG YOUR ERRORS, DON'T CATCH ALL return res.json({ success: false }); }); }); };});
This would let you do:
router.getP('/', function(req, res) { return somePromise.then(function doesSomething(someVariable) { doSomething; });});
Which will now catch errors automatically and send the appropriate JSON. Eliminating duplication or the possibility to forget errors altogether.
Pretty much like Ben Fortune's solution, using bind()
:
function catchesError(res, err) { return res.json({ success: false });}router.get('/', function(req, res) { return somePromise .then(function doesSomething(someVariable) { doSomething; }) .catch(catchesError.bind(null, res));});
Replace null with this
if you're in a class.