How can I output compiler errors of views generated from Hapi.js views?

In the express world, if there was an error compiling a Jade template, the error would output to the browser information about the template error, including the line number. I would like to see this level of error detail in Hapi.js when the view template compiler encounters an error.

Instead of Hapi.js, I get 500 Internal Server Error. The only output I see in the logs is the following:

150511/005652.910, [response], http://localhost:3000: get /abc123 {} 500 (24ms)

      

These are the basic settings for my setup.


var Hapi = require('hapi');
var server = new Hapi.Server();
server.connection({ port: 3000 });

server.views({
  engines: { jade: require('jade') },
  path: __dirname + '/views',
  compileOptions: {
    pretty: true,
    debug: true,
    compileDebug: true
  }
});

server.route({
  method: 'GET',
  path: '/{name}',
  handler: function (request, reply) {
    reply.view('page', {name: request.params.name});
  }
});

// I know putting my plugins in an array is not necessary but I like it.
var plugins = [{
  register: Good,
  options: {
    reporters: [{
      reporter: require('good-console'),
      events: {
        response: '*',
        log: '*'
      }
    }]
  }
}];

server.register(plugins, function (err) {
  if (err) {
    throw err; // something bad happened loading the plugin
  }

  server.start(function () {
    server.log('info', 'Server running at: ' + server.info.uri);
  });
});

      

+3


source to share


3 answers


Had the same problem this week.

var server = new Hapi.Server({
  debug: {
    request: ['error']
  }
});

      



It won't output to the client (you'll still get a 500 error), but a compilation error will appear in the terminal console.

+6


source


Since the rendering of the template happens after onPreResponse

, it is impossible to catch the error at this point. The way to send an error to the browser, albeit a slightly hacky one, is to do a dry compile run inside the extension point and then pass that error to the browser at that point:

server.ext('onPreResponse', function (request, reply) {

    var response = request.response;

    if (response.variety === 'view') {
        var source = response.source;

        // Let pre-render the template here and see if there any errors

        return server.render(source.template, source.context, function (err) {

            if (err) {
                return reply(err.message);    // transmit the compile error to browser
            }

            reply.continue();
        });
    }

    reply.continue();
});

      



Obviously this has a performance impact, because you render the view twice under normal conditions, so you want to turn it off in production.

+2


source


One possible solution is to register an error request with the server. For example:

server.on('request-error', function (request, err) {
  //logs the object
  server.log('error', err);

  //logs the view compiler error line number and details
  server.log('error', err.toString()); 
});

      

I'd rather see this in the browser (while in "development mode") in addition to the logs.

+1


source







All Articles