always-panic - v0.10.1
    Preparing search index...

    Class UnexpectedError<C>

    Bucket for unexpected failures (usually from fromAny after .try()).

    Temporary inside integration code: refine UNKNOWN into domain TypedErrors, then call result.panic on what remains before exporting — unexpected errors should always panic inside your package, not propagate downstream.

    Enables causeForUnwrap so unwrap/expect attach this error (and its cause chain) when tracing upstream bugs.

    Type Parameters

    Hierarchy (View Summary)

    Index

    Constructors

    • info is required exactly when the info map's entry for code is not undefined-able — that requiredness is what makes the per-code info types of is and match sound.

      Subclasses normally do not declare a constructor (a super call cannot resolve the conditional info tuple while the code parameter is still generic). name is set from the runtime class name automatically; declare a field (override name = 'XError') if it must survive minification.

      Type Parameters

      Parameters

      • code: C
      • message: string
      • ...__namedParameters: undefined extends Partial<Record<number, unknown>>[C]
            ? [info?: Partial<Record<number, unknown>>[C]]
            : [info: Partial<Record<number, unknown>>[C]]

      Returns UnexpectedError<C>

    Properties

    cause?: unknown

    The cause of the error.

    causeForUnwrap: boolean = true
    code: C
    info: Partial<Record<number, unknown>>[C]
    message: string
    name: string = 'UnexpectedError'
    stack?: string
    stackTraceLimit: number

    The Error.stackTraceLimit property specifies the number of stack frames collected by a stack trace (whether generated by new Error().stack or Error.captureStackTrace(obj)).

    The default value is 10 but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed.

    If set to a non-number value, or set to a negative number, stack traces will not capture any frames.

    Methods

    • Creates a .stack property on targetObject, which when accessed returns a string representing the location in the code at which Error.captureStackTrace() was called.

      const myObject = {};
      Error.captureStackTrace(myObject);
      myObject.stack; // Similar to `new Error().stack`

      The first line of the trace will be prefixed with ${myObject.name}: ${myObject.message}.

      The optional constructorOpt argument accepts a function. If given, all frames above constructorOpt, including constructorOpt, will be omitted from the generated stack trace.

      The constructorOpt argument is useful for hiding implementation details of error generation from the user. For instance:

      function a() {
      b();
      }

      function b() {
      c();
      }

      function c() {
      // Create an error without stack trace to avoid calculating the stack trace twice.
      const { stackTraceLimit } = Error;
      Error.stackTraceLimit = 0;
      const error = new Error();
      Error.stackTraceLimit = stackTraceLimit;

      // Capture the stack trace above function b
      Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
      throw error;
      }

      a();

      Parameters

      • targetObject: object
      • OptionalconstructorOpt: Function

      Returns void

    • Create .stack property on a target object

      Parameters

      • targetObject: object
      • OptionalconstructorOpt: Function

      Returns void

    • Type guard for "is this error mine, and (optionally) one of these codes?".

      Narrows unknown to the subclass instance, and — when codes are given — narrows code and info (via IsCode) to just those codes, replacing the e.code as XErrorCode cast that a wide Err union otherwise forces. Union members that are already narrower than the class (e.g. XError<A> in XError<A> | YError<B>) are kept as-is, so a following match still exhausts only the value's codes.

      Type Parameters

      • T extends new (...args: never) => TypedError<number>

      Parameters

      • this: T
      • e: unknown

        The value to test (usually an Err payload of a wide union).

      Returns e is InstanceType<T>

      Whether e is an instance of this class.

      if (ParseError.is(e)) e.code // ParseErrorCode
      
    • Type guard narrowing to this class and one of codes.

      The predicate (IsCode) is computed from the argument's type, so on a distributed union (XError<A> | XError<B>, the shape produced by narrowly-typed factories) a fully matched member is also subtracted in the false branch — recovering one code inside orElse trims it from the resulting error union, exactly like === narrowing on code. A single wide instantiation (XError<A | B>) cannot be subtracted from; for exhaustively mapping codes, use match.

      Type Parameters

      • T extends new (...args: never) => TypedError<number>
      • E
      • const C extends any

      Parameters

      • this: T
      • e: E

        The value to test (usually an Err payload of a wide union).

      • ...codes: C[]

        Codes to accept.

      Returns e is IsCode<E, InstanceType<T>, C>

      Whether e is an instance of this class with a matching code.

      // recover one code; EMPTY_INPUT is trimmed from the error union
      parseItems(input).orElse((e) =>
      ParseError.is(e, ParseErrorCode.EMPTY_INPUT) ? ok([]) : err(e),
      )
    • Indicates whether the argument provided is a built-in Error instance or not.

      Parameters

      • error: unknown

      Returns error is Error

    • Check if a value is an instance of Error

      Parameters

      • value: unknown

        The value to check

      Returns value is Error

      True if the value is an instance of Error, false otherwise

    • Exhaustively map an error of this class to a value, one handler per code — the equivalent of Rust's match on an error enum.

      Exhaustiveness is keyed on the value's static type, not the class's full enum: an error typed XError<A | B> (or XError<A> | XError<B>) requires handlers for exactly A and B. When upstream widens a function's error union with a new code, every match on it without else fails to compile, naming exactly the missing code.

      Each handler receives the error with code and info narrowed to its branch (info per-code requires the info-map type parameter on the class). Add an else handler to cover any subset of codes instead; else receives the un-narrowed error.

      This is a static method (XError.match(e, ...), not e.match(...)) because distributed unions like XError<A> | XError<B> — the shape produced by separate err() branches — cannot dispatch a generic instance method. Calling it on the class also rejects values of other error classes, whose numeric codes would otherwise collide.

      Type Parameters

      Parameters

      • this: T
      • e: E

        The error to match on.

      • handlers: H

        One handler per code in e's type, or a subset plus else.

      Returns ReturnType<H[keyof H & CodeContent<E>]>

      The union of the handlers' return types.

      When no handler matches at runtime — only possible when e's static type lies (e.g. a stale build or an unchecked cast).

      declare const e: ParseError<ParseErrorCode.EMPTY_INPUT | ParseErrorCode.BAD_TOKEN>
      // exhaustive: every code in the value's type is required
      const msg = ParseError.match(e, {
      [ParseErrorCode.EMPTY_INPUT]: () => 'nothing to parse',
      [ParseErrorCode.BAD_TOKEN]: (e) => `bad token ${e.info.token}`,
      })
      // partial: any subset plus `else`
      const msg2 = ParseError.match(e, {
      [ParseErrorCode.BAD_TOKEN]: (e) => `bad token ${e.info.token}`,
      else: (e) => e.message,
      })
      // recovery inside orElse: handlers that keep a code return err(e) with e
      // narrowed to that code, so recovered codes are ERASED from the union
      res.orElse((e) => ParseError.match(e, {
      [ParseErrorCode.EMPTY_INPUT]: () => ok([]),
      [ParseErrorCode.BAD_TOKEN]: (e) => err(e), // e: ParseError<BAD_TOKEN>
      })) // Result<Item[], ParseError<ParseErrorCode.BAD_TOKEN>>
      // (`else` receives the un-narrowed error, so erasure needs the exhaustive form)
    • Exhaustively map an error of this class to a value, one handler per code — the equivalent of Rust's match on an error enum.

      Exhaustiveness is keyed on the value's static type, not the class's full enum: an error typed XError<A | B> (or XError<A> | XError<B>) requires handlers for exactly A and B. When upstream widens a function's error union with a new code, every match on it without else fails to compile, naming exactly the missing code.

      Each handler receives the error with code and info narrowed to its branch (info per-code requires the info-map type parameter on the class). Add an else handler to cover any subset of codes instead; else receives the un-narrowed error.

      This is a static method (XError.match(e, ...), not e.match(...)) because distributed unions like XError<A> | XError<B> — the shape produced by separate err() branches — cannot dispatch a generic instance method. Calling it on the class also rejects values of other error classes, whose numeric codes would otherwise collide.

      Type Parameters

      Parameters

      • this: T
      • e: E

        The error to match on.

      • handlers: H

        One handler per code in e's type, or a subset plus else.

      Returns ReturnType<Extract<H[keyof H], (e: never) => unknown>>

      The union of the handlers' return types.

      When no handler matches at runtime — only possible when e's static type lies (e.g. a stale build or an unchecked cast).

      declare const e: ParseError<ParseErrorCode.EMPTY_INPUT | ParseErrorCode.BAD_TOKEN>
      // exhaustive: every code in the value's type is required
      const msg = ParseError.match(e, {
      [ParseErrorCode.EMPTY_INPUT]: () => 'nothing to parse',
      [ParseErrorCode.BAD_TOKEN]: (e) => `bad token ${e.info.token}`,
      })
      // partial: any subset plus `else`
      const msg2 = ParseError.match(e, {
      [ParseErrorCode.BAD_TOKEN]: (e) => `bad token ${e.info.token}`,
      else: (e) => e.message,
      })
      // recovery inside orElse: handlers that keep a code return err(e) with e
      // narrowed to that code, so recovered codes are ERASED from the union
      res.orElse((e) => ParseError.match(e, {
      [ParseErrorCode.EMPTY_INPUT]: () => ok([]),
      [ParseErrorCode.BAD_TOKEN]: (e) => err(e), // e: ParseError<BAD_TOKEN>
      })) // Result<Item[], ParseError<ParseErrorCode.BAD_TOKEN>>
      // (`else` receives the un-narrowed error, so erasure needs the exhaustive form)