Menu Close

Server-Side Development with Hapi.js — Throwing Errors

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.

Posted in Hapi