Bounce

repository·master·Indexed 41 days ago

https://github.com/hapijs/bounce

A utility for selective error catching and rewrite rules, allowing developers to distinguish between application and system errors. It provides methods like rethrow(), ignore(), and background() to intercept specific errors and transform them or handle them according to custom logic. While part of the hapi ecosystem, it is a standalone module compatible with any Node.js application.

Tokens
2.3K
Snippets
7
Records
11
Agent score
52%

What's inside Bounce

  1. Overview of @hapi/bounce

    master
    @hapi/bounce is a utility for selective error catching and rewrite rules. While it is part of the hapi ecosystem and designed to work seamlessly with the hapi web framework, it is a standalone module that can be used with any other framework or in general Node.js applications.
  2. Use Bounce to distinguish between application and system errors

    master

    When using async/await, application errors (expected failures) and system/developer errors (unexpected bugs) are both thrown as exceptions. This makes it easy to accidentally swallow critical developer errors when trying to ignore non-critical application errors.

    @hapi/bounce allows you to selectively rethrow system errors while ignoring application errors. This ensures that while a non-critical task (like sending an email) might fail silently for a user, a developer error (like a TypeError due to a bug) will still surface and crash the process or trigger error reporting.

    const Bounce = require('@hapi/bounce');
    
    try {
        await email(user);
    } catch (err) {
        // Rethrows system errors (bugs) and ignores application errors (expected failures)
        Bounce.rethrow(err, 'system');
    }
  3. Error matching criteria for types

    master

    When using rethrow, ignore, or background, the types parameter determines which errors are caught. You can match errors using several strategies:

    1. Predefined Rule Strings:
      • 'system': Matches standard JavaScript and Node.js system errors (e.g., TypeError, RangeError, AssertionError).
      • 'boom': Matches @hapi/boom errors.
    2. Constructors:
      • Pass a class/constructor (e.g., TypeError) to match via instanceof.
    3. Objects:
      • Pass an object to perform a deep containment check (using @hapi/hoek).
    4. Arrays:
      • Pass an array of any of the above to match if the error satisfies any one of the criteria.
  4. Rethrow specific error types with rethrow()

    master

    The rethrow(err, types, [options]) method throws the error if it matches any of the specified rules. This is used to ensure critical errors are not swallowed in catch blocks.

    Arguments:

    • err: The error object to check.
    • types: A single item or an array of:
      • An error constructor (e.g., SyntaxError).
      • 'system': Matches language-native errors or Node assertions.
      • 'boom': Matches boom errors.
      • An object: Matches if all properties in the object match the error's properties.
    • options (optional object):
      • decorate: An object to copy properties onto the err.
      • override: An error to use instead of err if it matches. If decorate is used, the override object is modified.
      • return: If true, the error is returned instead of thrown (defaults to false).
    // Example: Rethrowing system errors
    Bounce.rethrow(err, 'system');
    
    // Example: Rethrowing specific error constructors
    Bounce.rethrow(err, [TypeError, ReferenceError]);
    
    // Example: Rethrowing based on property matching
    Bounce.rethrow(err, { code: 404 });
  5. Ignore specific error types with ignore()

    master

    The ignore(err, types, [options]) method is the opposite of rethrow(). It ignores any errors matching the specified types. Any error that does not match the criteria is thrown after applying the provided options.

    // Example: Ignore only boom errors
    Bounce.ignore(err, 'boom');
  6. Run background operations with background()

    master

    The background(operation, [action], [types], [options]) method allows you to await a value in the background and automatically apply either a rethrow or ignore strategy to any errors encountered.

    Arguments:

    • operation: A function, promise, or value to be awaited inside a try...catch.
    • action: 'rethrow' or 'ignore'. Defaults to 'rethrow'.
    • types: Same as rethrow() or ignore(). Defaults to 'system'.
    • options: Same as rethrow() or ignore().
    // Example: Run an operation in the background, ignoring application errors but rethrowing system errors
    await Bounce.background(email(user), 'ignore', 'system');
  7. Identify error types with isBoom, isError, and isSystem

    master

    Bounce provides utility methods to check the nature of an error:

    • isBoom(err): Returns true if err is a boom error.
    • isError(err): Returns true if err is an error.
    • isSystem(err): Returns true if err is a language-native error or Node assertion. Specifically matches:
      • EvalError
      • RangeError
      • ReferenceError
      • SyntaxError
      • TypeError
      • URIError
      • Node's AssertionError
  8. Run an operation in the background with background()

    master

    Use background(operation, action, types, options) to execute an asynchronous operation and handle any resulting errors using Bounce's logic.

    Parameters:

    • operation (Function | Promise): The async operation to perform.
    • action (string): Which Bounce method to call if the operation fails. Defaults to 'rethrow'. Valid values are 'rethrow' or 'ignore'.
    • types (string | Array | undefined): The error types to match against. Defaults to 'system'.
    • options (Object): Options passed to the chosen action method.
    const Bounce = require('@hapi/bounce');
    
    // Run an operation that ignores system errors in the background
    await Bounce.background(
        async () => {
            await someAsyncWork();
        },
        'ignore',
        'system'
    );
  9. Check error types with isBoom(), isError(), and isSystem()

    master

    Bounce provides utility methods to inspect error types:

    • isBoom(err): Returns true if the error is a @hapi/boom error.
    • isError(err): Returns true if the error is an instance of Error.
    • isSystem(err): Returns true if the error is a standard JavaScript system error (e.g., TypeError, ReferenceError, SyntaxError) or a Node.js Assert.AssertionError. It returns false if the error is a Boom error or if no error is provided.
  10. Ignore an error with ignore()

    master

    Use ignore(err, types, options) to conditionally swallow an error. If the error matches the provided types, the function returns undefined. If it does not match, the error is thrown.

    Parameters:

    • err (Error): The error to evaluate.
    • types (string | Array<string|object|Constructor> | undefined): Criteria to match the error against.
    • options (Object): Configuration for error transformation.
      • options.override (Error): If provided, the original error is replaced by this error before returning.
      • options.decorate (Object): Properties to assign to the error object via Object.assign.
      • options.return (Error): If provided, instead of returning undefined, the function returns this error object.
    const Bounce = require('@hapi/bounce');
    
    try {
        // ... some logic
    } catch (err) {
        // Ignore if it's a specific error type, otherwise rethrow it
        Bounce.ignore(err, TypeError);
    }
  11. Rethrow an error with rethrow()

    master

    Use rethrow(err, types, options) to conditionally throw an error based on its type. If the error matches the provided types, it is thrown. If it does not match, the function returns undefined (effectively swallowing the error).

    Parameters:

    • err (Error): The error to evaluate.
    • types (string | Array<string|object|Constructor> | undefined): Criteria to match the error against.
      • If a string is provided, it checks against predefined rule sets: 'system' or 'boom'.
      • If an object is provided, it performs a deep containment check.
      • If a Constructor is provided, it uses instanceof.
      • If undefined, all errors match.
    • options (Object): Configuration for error transformation.
      • options.override (Error): If provided, the original error is replaced by this error before throwing.
      • options.decorate (Object): Properties to assign to the error object via Object.assign.
      • options.return (Error): If provided, instead of throwing, the function returns this error object.
    const Bounce = require('@hapi/bounce');
    
    try {
        // ... some logic that fails
    } catch (err) {
        // Rethrow if it's a system error, otherwise do nothing
        Bounce.rethrow(err, 'system');
    }