From d3781136d0907cfc2bb8f70909145af2acbd1969 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Tue, 10 May 2016 07:54:33 -0700 Subject: [PATCH] add support for error post hooks --- index.js | 54 +++++++++++++++++++++++-------- test/post.test.js | 81 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 14 deletions(-) diff --git a/index.js b/index.js index 819f1bc..96d79a8 100644 --- a/index.js +++ b/index.js @@ -108,7 +108,11 @@ Kareem.prototype.execPreSync = function(name, context) { } }; -Kareem.prototype.execPost = function(name, context, args, callback) { +Kareem.prototype.execPost = function(name, context, args, options, callback) { + if (arguments.length < 5) { + callback = options; + options = null; + } var posts = this._posts[name] || []; var numPosts = posts.length; var currentPost = 0; @@ -119,29 +123,53 @@ Kareem.prototype.execPost = function(name, context, args, callback) { }); } + var firstError = null; + if (options && options.error) { + firstError = options.error; + } var next = function() { var post = posts[currentPost]; - if (post.length > args.length) { - post.apply(context, args.concat(function(error) { - if (error) { - return callback(error); + if (firstError) { + if (post.length === args.length + 2) { + post.apply(context, [firstError].concat(args).concat(function(error) { + if (error) { + firstError = error; + } + if (++currentPost >= numPosts) { + return callback.call(null, firstError); + } + next(); + })); + } else { + if (++currentPost >= numPosts) { + return callback.call(null, firstError); } + next(); + } + } else { + if (post.length === args.length + 1) { + post.apply(context, args.concat(function(error) { + if (error) { + firstError = error; + return next(); + } + + if (++currentPost >= numPosts) { + return callback.apply(null, [null].concat(args)); + } + + next(); + })); + } else { + post.apply(context, args); if (++currentPost >= numPosts) { return callback.apply(null, [null].concat(args)); } next(); - })); - } else { - post.apply(context, args); - - if (++currentPost >= numPosts) { - return callback.apply(null, [null].concat(args)); } - - next(); } }; diff --git a/test/post.test.js b/test/post.test.js index bf8bba5..9fcbb0e 100644 --- a/test/post.test.js +++ b/test/post.test.js @@ -43,6 +43,85 @@ describe('execPost', function() { done(); }); }); + + it('error posts', function(done) { + var called = {}; + hooks.post('cook', function(eggs, callback) { + called.first = true; + callback(); + }); + + hooks.post('cook', function(eggs, callback) { + called.second = true; + callback(new Error('fail')); + }); + + hooks.post('cook', function(eggs, callback) { + assert.ok(false); + }); + + hooks.post('cook', function(error, eggs, callback) { + called.fourth = true; + assert.equal(error.message, 'fail'); + callback(new Error('fourth')); + }); + + hooks.post('cook', function(error, eggs, callback) { + called.fifth = true; + assert.equal(error.message, 'fourth'); + callback(new Error('fifth')); + }); + + hooks.execPost('cook', null, [4], function(error, eggs) { + assert.ok(error); + assert.equal(error.message, 'fifth'); + assert.deepEqual(called, { + first: true, + second: true, + fourth: true, + fifth: true + }); + done(); + }); + }); + + it('error posts with initial error', function(done) { + var called = {}; + + hooks.post('cook', function(eggs, callback) { + assert.ok(false); + }); + + hooks.post('cook', function(error, eggs, callback) { + called.second = true; + assert.equal(error.message, 'fail'); + callback(new Error('second')); + }); + + hooks.post('cook', function(error, eggs, callback) { + called.third = true; + assert.equal(error.message, 'second'); + callback(new Error('third')); + }); + + hooks.post('cook', function(error, eggs, callback) { + called.fourth = true; + assert.equal(error.message, 'third'); + callback(); + }); + + var options = { error: new Error('fail') }; + hooks.execPost('cook', null, [4], options, function(error, eggs) { + assert.ok(error); + assert.equal(error.message, 'third'); + assert.deepEqual(called, { + second: true, + third: true, + fourth: true + }); + done(); + }); + }); }); describe('execPostSync', function() { @@ -73,4 +152,4 @@ describe('execPostSync', function() { hooks.execPostSync('cook', null); }); }); -}); \ No newline at end of file +});