API Reference

This API reference will give you specific details on how to use each function. It's intended that you've read through The Big Picture first, to give you a grasp of how these functions work together.

wrap(fnToWrap, allowedExceptionTypes = null)

Decorates the provided fnToWrap, such that the wrapper will always return a maybe type, whether or not the wrapped function threw an exception or returned a value. It is intended that the users of this wrapped function use unwrap() to retrieve the original returned value

Parameters:

  • fnToWrap The function to be wrapped. if fnToWrap is async, wrapAsync() should be used instead to properly wrap the entire async body.

  • allowedExceptionTypes Optional list of exceptions this function may propagate. Defaults to allowing all. Any thrown exception not found in this list will be escalated (i.e. an instance of Error will be thrown instead, explaining what happened).

returns: A maybe type, intended to be unwrapped with unwrap()

The maybe instance returned by a wrap() function must at some point be unwrapped by the unwrap() function. It is considered a bug if the return value is ignored. If you wish to ignore the return value of a wrapped function and escalate any exceptions it provides, you must do so explicitly with the unwrap call, like this unwrap(someWrappedFn(), []), or more simply unwrap(someWrappedFn()).

The allowedExceptionTypes list is intended to be used by those who wish to provide self-documentation of the types of exceptions a function may throw, without requiring the user to look through the body of the function. For example:

const getEntry = wrap(id => {
  if (!data.has(id)) {
    // Throws our custom Exception instance, with the intention that
    // our caller would be able to catch and handle this.
    throw new Exception('NotFound')
  }
  return data.get(id)
}, ['NotFound'])

In the above example, you can know that getEntry() will only provide the NotFound exception, because any other exceptions would have been escalated, as they were not found in the allowedExceptionTypes list.

If an unhandled maybe instance gets garbage collected, a warning will be logged informing you of the forgotten unwrap() call. Note that you can't depend on these warnings to show up - depending on the javascript implementation and how large your program is, it's possible that the garbage collector doesn't even run during the lifetime of your program. In node, to help debug issues and force these warnings to show up, you can force-schedule the garbage collector to run by starting node with the --expose-gc flag, then calling the now-available global gc() function.

wrapAsync(fnToWrap, allowedExceptionTypes = null)

Same as wrap(), except it expects fnToWrap() to return a promise. The entire promise will be wrapped, and wrapAsync() itself will return a promise that resolves into a Maybe type.

unwrap(maybeValue, allowedExceptionTypes = [])

Unwraps a maybe type. One of three possible scenarios will happen:

  • If the maybe type contains an "ok" value, its content will be returned.

  • If the maybe type contains an exception whose code is found in allowedExceptionTypes, the exception will be rethrown.

  • If the maybe type contains an exception whose code is not found in allowedExceptionTypes, the exception will be escalated (meaning, a new Error() instance will be thrown, explaining that this specific exception was unhandled).

new Exception(code, message = null, data = null)

Creates a new Exception instance, that's meant to be thrown within a wrapped function. Never throw it outside of a wrapped function - this goes against the entire philosophy of explicit-exceptions. In the future, we may provide linter rules to help enforce this.

An Exception is a subclass of an Error, which means it'll contain an error message and stack trace, just like a normal error.

Parameters:

  • code Gets set as the "code" property on the exception instance. Can be used to programmatically distinguish one exception from another. Other functions provided by explicit-exceptions will use this property for this exact purpose.

  • message (optional) Both the code and the optional message value will be used together to create the "message" property of the exception. This message property will be used to provide additional debugging information if the exception escalates to a fatal error.

  • data (optional) Any arbitrary data that you wish to attach to the exception instance (under the "data" property).

Last updated