Hapi.js is a small Node framework for developing back end web apps.
In this article, we’ll look at how to create back end apps with Hapi.js.
Throw Unauthorized Errors
We can throw unauthorized errors with the @hapi/boom
module.
It has the Boom.unauthorized
method to throw the error.
For instance, we can write:
const Hapi = require('@hapi/hapi');
const Boom = require('@hapi/boom');
const init = async () => {
const server = new Hapi.Server({
port: 3000,
host: '0.0.0.0'
});
server.route({
method: 'GET',
path: '/',
handler(request, h) {
throw Boom.unauthorized('invalid password');
}
});
await server.start();
console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
We call Boom.unauthorized
method with a message to create the 401 response.
Now we should get:
{"statusCode":401,"error":"Unauthorized","message":"invalid password"}
when we make a GET request to the /
route.
We can pass in extra data in the 3rd argument.
For example, we can write:
const Hapi = require('@hapi/hapi');
const Boom = require('@hapi/boom');
const init = async () => {
const server = new Hapi.Server({
port: 3000,
host: '0.0.0.0'
});
server.route({
method: 'GET',
path: '/',
handler(request, h) {
throw Boom.unauthorized('invalid password', 'sample', { ttl: 0, cache: null, foo: 'bar' });
}
});
await server.start();
console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
The object in the 3rd argument will be added to the attributes
property of the response.
So we get:
{"statusCode":401,"error":"Unauthorized","message":"invalid password","attributes":{"ttl":0,"cache":"","foo":"bar","error":"invalid password"}}
as the response.
The 2nd argument will be in the Www-Authenticate
response header.
We get:
sample ttl="0", cache="", foo="bar", error="invalid password"
as its value.
Payment Required Response
We can return a 402 response with the Boom.paymentRequired
method.
For instance, we can write:
const Hapi = require('@hapi/hapi');
const Boom = require('@hapi/boom');
const init = async () => {
const server = new Hapi.Server({
port: 3000,
host: '0.0.0.0'
});
server.route({
method: 'GET',
path: '/',
handler(request, h) {
throw Boom.paymentRequired('bandwidth used');
}
});
await server.start();
console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
We call Boom.paymentRequied
with the message that we want to return.
Then we get:
{"statusCode":402,"error":"Payment Required","message":"bandwidth used"}
as the response.
Forbidden Error
We can throw a forbidden error with the Boom.forbidden
method:
const Hapi = require('@hapi/hapi');
const Boom = require('@hapi/boom');
const init = async () => {
const server = new Hapi.Server({
port: 3000,
host: '0.0.0.0'
});
server.route({
method: 'GET',
path: '/',
handler(request, h) {
throw Boom.forbidden('try again some time');
}
});
await server.start();
console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
Then we get:
{"statusCode":403,"error":"Forbidden","message":"try again some time"}
as the response.
Not Found Error
We can return a 404 error with the Boom.notFound
method:
const Hapi = require('@hapi/hapi');
const Boom = require('@hapi/boom');
const init = async () => {
const server = new Hapi.Server({
port: 3000,
host: '0.0.0.0'
});
server.route({
method: 'GET',
path: '/',
handler(request, h) {
throw Boom.notFound('missing');
}
});
await server.start();
console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
Then we should get:
{"statusCode":404,"error":"Not Found","message":"missing"}
as the response.
Conclusion
We can throw various kinds of errors easily with the @hapi/boom
module.