Skip to content

Commit

Permalink
Merge pull request #3202 from hapijs/detach-promises
Browse files Browse the repository at this point in the history
Delay continuations when promises may be involved
  • Loading branch information
hueniverse authored Aug 22, 2016
2 parents f91bcf1 + 83b3a09 commit f8b58ea
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 9 deletions.
8 changes: 4 additions & 4 deletions lib/methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,15 @@ internals.Methods.prototype._add = function (name, method, options, realm) {

// Promise object

const onFulfilled = (outcome) => {
const onFulfilled = Hoek.nextTick((outcome) => {

return methodNext(null, outcome);
};
});

const onRejected = (err) => {
const onRejected = Hoek.nextTick((err) => {

return methodNext(err);
};
});

result.then(onFulfilled, onRejected);
};
Expand Down
2 changes: 1 addition & 1 deletion lib/protect.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ internals.Protect.prototype.run = function (next, enter) { // enter
return finish(Boom.badImplementation('Uncaught error', err));
};

enter(finish);
this.domain.bind(enter)(finish);
};


Expand Down
7 changes: 5 additions & 2 deletions lib/reply.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,11 @@ internals.close = function (options) {

internals.continue = function (data) {

this._next(null, data);
this._next = null;
Hoek.nextTick(() => {

this._next(null, data);
this._next = null;
})();
};


Expand Down
4 changes: 2 additions & 2 deletions lib/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ internals.Response.prototype._prepare = function (data, next) {
return this._processPrepare(data, next);
}

const onDone = (source) => {
const onDone = Hoek.nextTick((source) => {

if (source instanceof Error) {
return next(Boom.wrap(source), data);
Expand All @@ -473,7 +473,7 @@ internals.Response.prototype._prepare = function (data, next) {
this._setSource(source);
this._passThrough();
this._processPrepare(data, next);
};
});

this.source.then(onDone, onDone);
};
Expand Down
44 changes: 44 additions & 0 deletions test/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,50 @@ describe('Request', () => {
});
});

it('emits request-error on implementation error with a promise in pre handler', (done) => {

const server = new Hapi.Server({ debug: false });
server.connection();

let errs = 0;
let req = null;
server.on('request-error', (request, err) => {

++errs;
expect(err).to.exist();
expect(err.message).to.equal('Uncaught error: boom');
req = request;
});

const handler = function (request, reply) {

throw new Error('boom');
};

server.route({ method: 'GET', path: '/', handler: handler });

server.ext('onPreHandler', (request, reply) => {

Promise.resolve()
.then(() => reply.continue())
.catch(() => reply(Boom.badImplementation('oops')));
});

server.once('response', () => {

expect(errs).to.equal(1);
expect(req.getLog('error')[0].tags).to.equal(['internal', 'implementation', 'error']);
done();
});

server.inject('/', (res) => {

expect(res.statusCode).to.equal(500);
expect(res.result).to.exist();
expect(res.result.message).to.equal('An internal server error occurred');
});
});

it('does not emit request-error when error is replaced with valid response', (done) => {

const server = new Hapi.Server({ debug: false });
Expand Down

0 comments on commit f8b58ea

Please sign in to comment.