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);
});
});
source to share
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.
source to share
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.
source to share