Hapi: thrown errors inside server.inject does not propagate

Created on 6 Jan 2014  Â·  10Comments  Â·  Source: hapijs/hapi

The thrown error never appears in the console.

var server = require('hapi').createServer('localhost', 8000);
server.route({
  method: 'GET',
  path: '/',
  handler: function (request, reply) {
    reply('hello world');
  }
});

server.inject({method: 'GET', url: '/'}, function (res) {
  throw new Error('Never shown')
  console.log(res.result)
})
bug

All 10 comments

I don't know what is the state of mocha support for node domains. hapi uses a domains a lot. This was the main reason we moved away from mocha and are using lab instead. If you look at the hapi tests, we use chai which throws inside server.inject() all the time.

No, don't close this issue! It has nothing to do with Mocha and if you take a second look at the example code I provided you will see that it does not contain any Mocah related code – it is pure Hapi. Thrown errors does not proppogate from inside server.inject; but this might be an issue with shot instead of hapi?

This is odd. I can see the error if I wrap it in a domain:

var Hapi = require('hapi');
var Domain = require('domain');


var domain = Domain.createDomain();
domain.run(function () {

    var server = new Hapi.Server(8000);
    server.route({
        method: 'GET',
        path: '/',
        handler: function (request, reply) {

            reply('hello world');
        }
    });

    server.inject({ method: 'GET', url: '/' }, function (res) {

        throw new Error('Never shown');
        console.log(res.result);
    });
});

domain.on('error', function (err) {

    console.log(err.stack);
});

@Starefossen what other modules do you use in your system? I've just narrowed down some issues to either Q, or buster, or referree (buster's assertion library). Or my incorrect usage of these - not sure yet.

Disregard that. The initial code clearly shows there is also a problem in hapi, as well as elsewhere.

To save people some searching, this _is_ a mocha issue (and probably one w/ most other JS test frameworks). Mocha wraps all tests in a try/catch block which is what's causing this issue. The try/catch swallows the synchronous exceptions from assertions and those exceptions never makes it up to the domain's error handler. The try/catch is helpful for browser support, but with domains and uncaughtException handlers in Node there's no reason for it. You can fork Mocha and patch runnable and runner or the equivalents for Buster et al. Or use Lab.

Further reading: https://github.com/visionmedia/mocha/issues/513

@bendrucker if you run the code snippet I have provided in the first post – or read my second comment – you can see that this error is reproducible without requiring any modules except for hapi itself. Hence, this _is_ a hapi error.

So you're expecting the thrown exception to emit an uncaughtException event on process? I originally came here having seen the issue with Mocha. I was assuming that you were just pulling the test code out of Mocha and interpreted "it has nothing to do with Mocha" to mean that you didn't think Mocha was the cause. In any case, just trying to be helpful.

I came to this issue after looking for a way to use mocha with hapi.
From what I can see this is easy to do with Promises.
Too bad hapi doesn't use promises out of the box, but we could easily wrap the inject method to return a promise and write tests like so -

require('should');
var Promise = require("bluebird"),
    server = require('../');
function inject (options) {
    return new Promise(function (resolve, reject) {
        server.inject(options, resolve);
    });
}

describe('api', function(){
    it('should have this route', function () {
        return inject({ method: "GET", url: "/api/missing_route"}).then(function (response) {
            //this will throw an error
            response.statusCode.should.eql(200);
        });
    });
});

@bendrucker Cool. I guess it's probably better to have this as a reusable plugin then what I did.
I would have completely remove the builtin inject and make the server.inject method promiseable ( I'll send you a pull request).
But I would be much more happy if Hapi had promises build in since callbacks in general become messy quite quickly. Its weird nobody asked it before (couldn't find any issues) so I submitted this issue #2097

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jney picture jney  Â·  4Comments

hueniverse picture hueniverse  Â·  4Comments

taoeffect picture taoeffect  Â·  3Comments

hueniverse picture hueniverse  Â·  4Comments

shamsher31 picture shamsher31  Â·  5Comments