Bounce
repository·master·Indexed 41 days ago
https://github.com/hapijs/bounceA 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.
What's inside Bounce
- @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.
Use Bounce to distinguish between application and system errors
masterWhen 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/bounceallows 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 aTypeErrordue 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'); }Error matching criteria for types
masterWhen using
rethrow,ignore, orbackground, thetypesparameter determines which errors are caught. You can match errors using several strategies:- Predefined Rule Strings:
'system': Matches standard JavaScript and Node.js system errors (e.g.,TypeError,RangeError,AssertionError).'boom': Matches@hapi/boomerrors.
- Constructors:
- Pass a class/constructor (e.g.,
TypeError) to match viainstanceof.
- Pass a class/constructor (e.g.,
- Objects:
- Pass an object to perform a deep containment check (using
@hapi/hoek).
- Pass an object to perform a deep containment check (using
- Arrays:
- Pass an array of any of the above to match if the error satisfies any one of the criteria.
- Predefined Rule Strings:
Rethrow specific error types with rethrow()
masterThe
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 incatchblocks.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.
- An error constructor (e.g.,
options(optional object):decorate: An object to copy properties onto theerr.override: An error to use instead oferrif it matches. Ifdecorateis used, theoverrideobject is modified.return: Iftrue, the error is returned instead of thrown (defaults tofalse).
// 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 });Ignore specific error types with ignore()
masterThe
ignore(err, types, [options])method is the opposite ofrethrow(). It ignores any errors matching the specifiedtypes. Any error that does not match the criteria is thrown after applying the providedoptions.// Example: Ignore only boom errors Bounce.ignore(err, 'boom');Run background operations with background()
masterThe
background(operation, [action], [types], [options])method allows you to await a value in the background and automatically apply either arethroworignorestrategy to any errors encountered.Arguments:
operation: A function, promise, or value to beawaited inside atry...catch.action:'rethrow'or'ignore'. Defaults to'rethrow'.types: Same asrethrow()orignore(). Defaults to'system'.options: Same asrethrow()orignore().
// Example: Run an operation in the background, ignoring application errors but rethrowing system errors await Bounce.background(email(user), 'ignore', 'system');Identify error types with isBoom, isError, and isSystem
masterBounce provides utility methods to check the nature of an error:
isBoom(err): Returnstrueiferris a boom error.isError(err): Returnstrueiferris an error.isSystem(err): Returnstrueiferris a language-native error or Node assertion. Specifically matches:EvalErrorRangeErrorReferenceErrorSyntaxErrorTypeErrorURIError- Node's
AssertionError
Run an operation in the background with background()
masterUse
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 chosenactionmethod.
const Bounce = require('@hapi/bounce'); // Run an operation that ignores system errors in the background await Bounce.background( async () => { await someAsyncWork(); }, 'ignore', 'system' );Check error types with isBoom(), isError(), and isSystem()
masterBounce provides utility methods to inspect error types:
isBoom(err): Returnstrueif the error is a@hapi/boomerror.isError(err): Returnstrueif the error is an instance ofError.isSystem(err): Returnstrueif the error is a standard JavaScript system error (e.g.,TypeError,ReferenceError,SyntaxError) or a Node.jsAssert.AssertionError. It returnsfalseif the error is a Boom error or if no error is provided.
Ignore an error with ignore()
masterUse
ignore(err, types, options)to conditionally swallow an error. If the error matches the providedtypes, the function returnsundefined. 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 viaObject.assign.options.return(Error): If provided, instead of returningundefined, 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); }Rethrow an error with rethrow()
masterUse
rethrow(err, types, options)to conditionally throw an error based on its type. If the error matches the providedtypes, it is thrown. If it does not match, the function returnsundefined(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
stringis provided, it checks against predefined rule sets:'system'or'boom'. - If an
objectis provided, it performs a deep containment check. - If a
Constructoris provided, it usesinstanceof. - If
undefined, all errors match.
- If a
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 viaObject.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'); }