bounce

Selective error catching and rewrite rules.

Latest Version: 2.0.0
hapi-family
Installation:

npm: npm install @hapi/bounce

yarn: yarn add @hapi/bounce

Module Status:
Version License Node Dependencies Travis End of Life
2.0.0
hapi helmet github logo
BSD 12 Dependency Status Build Status
1.3.2
hapi helmet github logo
Commercial 12, 10, 8 Dependency Status Build Status

Introduction

Working with async/await introduces a new challenge in handling errors. Unlike callbacks, which
provide a dual mechanism for passing application errors via the callback err argument and
developer errors via exceptions, await combines these two channels into one.

It is common practice to ignore application errors in background processing or when there is no
useful fallback. In those cases, it is still imperative to allow developer errors to surface and
not get swallowed.

For more information read:

For example:

async function email(user) {

    if (!user.address) {
        throw new Error('User has no email address');
    }

    const message = 'Welcome!';
    if (user.name) {
        message = `Welcome ${user.name}!`;
    }

    await mailer.send(user.address, message);
}

async function register(address, name) {

    const user = { address, name };
    const id = await db.user.insert(user);
    user.id = id;

    try {
        await email(user);
    }
    catch (err) { }             // Ignore errors

    return user;
}

This will fail silently every time the user has a name because it is reassigning a value to a
const variable. However, because email() errors are ignored, system errors are ignored as well.
The idea is that email() can be used in both critical and non-critical paths. In the critical
paths, errors are checked and addressed, but in the non-critical paths, errors are simply ignored.

This can be solved by adding a rethrow() statement:

const Bounce = require('@hapi/bounce');

async function register(address, name) {

    const user = { address, name };
    const id = await db.user.insert(user);
    user.id = id;

    try {
        await email(user);
    }
    catch (err) {
        Bounce.rethrow(err, 'system');  // Rethrows system errors and ignores application errors
    }

    return user;
}