I'm creating my first node.js REST web service using hapi.js. I'm curious as to the best way to handle errors let's say from my dao layer. Do i throw
them in my dao layer and then just try/catch
blocks to handle them and send back errors in my controller, or is there a better way that the cool kids are handling this?
routes/task.js
var taskController = require('../controllers/task');
//var taskValidate = require('../validate/task');
module.exports = function() {
return [
{
method: 'POST',
path: '/tasks/{id}',
config : {
handler: taskController.createTask//,
//validate : taskValidate.blah
}
}
]
}();
controllers/task.js
var taskDao = require('../dao/task');
module.exports = function() {
return {
/**
* Creates a task
*
* @param req
* @param reply
*/
createTask: function createTask(req, reply) {
taskDao.createTask(req.payload, function (err, data) {
// TODO: Properly handle errors in hapi
if (err) {
console.log(err);
}
reply(data);
});
}
}();
dao/task.js
module.exports = function() {
return {
createTask: function createTask(payload, callback) {
... Something here which creates the err variable...
if (err) {
console.log(err); // How to properly handle this bad boy
}
}
}();
We wrote a Hapi Plugin that handles all errors seamlessly: npmjs.com/package/hapi-error
It lets you define your own custom error pages in 3 easy steps.
npm install hapi-error --save
Include the plugin when you register
your server:
server.register([require('hapi-error'), require('vision')], function (err) {
// your server code here ...
});
See: /example/server_example.js for simple example
error_template
Note:
hapi-error
plugin expects you are usingVision
(the standard view rendering library for Hapi apps) which allows you to use Handlebars, Jade, React, etc. for your templates.
Your error_template.html
(or error_template.ext
error_template.jsx
) should make use of the 3 variables it will be passed:
errorTitle
- the error tile generated by Hapi
statusCode
- *HTTP statusCode sent to the client e.g: 404
(not found)errorMessage
- the human-friendly error message
for an example see:
/example/error_template.html
That's it! Now your Hapi App handles all types of errors and you can throw your own custom ones too!
Note:
hapi-error
works for REST/APIs too. if the content type header (headers.acceps
) is set toapplication/json
then your app will return a JSON error to the client, otherwise an HTML page will be served.
In doing more research along with Ricardo Barros' comment on using Boom, here's what I ended up with.
controllers/task.js
var taskDao = require('../dao/task');
module.exports = function() {
return {
/**
* Creates a task
*
* @param req
* @param reply
*/
createTask: function createTask(req, reply) {
taskDao.createTask(req.payload, function (err, data) {
if (err) {
return reply(Boom.badImplementation(err));
}
return reply(data);
});
}
}();
dao/task.js
module.exports = function() {
return {
createTask: function createTask(payload, callback) {
//.. Something here which creates the variables err and myData ...
if (err) {
return callback(err);
}
//... If successful ...
callback(null, myData);
}
}();
I think the cool kids now use a package to caught unhandled errors with Hapi, I present to you, Poop.
The only thing Poop is missing is some rich documentation, but check it out, and you'll see that Poop is great.
Some of my friends went to a node.js event in Lisbon, on of the hosts was a guy in charge of web technology stack at Wallmart, they use Hapi.js, Poop and some other cool things.
So if they use poop it must be pretty awesome.
PS: The name is suppa awesome
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With