Skip to content

Releases: rxova/ts-extended-errors

ts-extended-errors@1.0.1

Choose a tag to compare

Patch Changes

  • #51 280462b - Point links at rxova.dev.

  • #46 99388a7 - Take the safe property-read helpers from @rxova/ts-utils, inlined at build time. No behavior change, and still no runtime dependencies.

ts-extended-errors@1.0.0

Choose a tag to compare

Major Changes

  • #37 aa60b07 Thanks @jonatankruszewski! - Require Node.js 22.12 or newer. Node 20 reached end of life in April 2026, and a major release is
    the one moment the floor can move without surprising anyone. The code uses no Node.js APIs, so
    browsers and other runtimes are unaffected; the build now uses the workspace's Node 22 target.

  • #37 1a1eef0 Thanks @jonatankruszewski! - Version 1.0.0. The API that shipped through the 0.x releases is now stable: ExtendedError,
    defineError, the five cause-chain helpers, serializeError, deserializeError, toError,
    isErrorLike, describeValue and the exported types. From here, a breaking change to any of them,
    to the serialized shape, or to the defaults of toJSON and serializeError means a new major.

    What 1.0 settles on purpose: JSON.stringify(error) includes stack by default and is meant for
    logs, with includeStack: false for anything client-facing; a thrown value that is not an error
    serializes under name: typeof value; and cause chains are linear, following cause and never an
    AggregateError's errors.

Minor Changes

  • #37 9b8d427 Thanks @jonatankruszewski! - Accept any object type as a context type, an interface included. The Context type parameters of
    ExtendedError, defineError and the exported constructor types were constrained to
    Readonly<Record<string, unknown>>, which an interface fails for lack of an index signature, so
    defineError<UserContext>(…) was a type error whenever UserContext was declared with interface.
    The constraint is now object; ErrorContext stays the default.

  • #37 5e77158 Thanks @jonatankruszewski! - Type code as the literal a class declares. defineError('NotFoundError', { code: 'HTTP_NOT_FOUND' })
    now types code as 'HTTP_NOT_FOUND' on the class and on its instances, and a class defined without
    one is typed with its base's, so a switch over a taxonomy's codes can be exhaustive and a
    findCause predicate can narrow on one. ExtendedErrorConstructor, MessageErrorConstructor and
    DefineErrorOptions gain a Code type parameter after their existing ones, and ErrorCode, its
    constraint, is exported.

    Two consequences. Naming Context as a type argument leaves code at string | undefined, because
    TypeScript infers all of a call's type arguments or none; name Code as well,
    defineError<Context, 'X'>(…), to keep the literal. And a class-syntax subclass of a defineError
    class can no longer declare a different static code, since its instance type already carries the
    base's literal; define the leaf with defineError and extend that.

  • #37 51303b3 Thanks @jonatankruszewski! - Keep a numeric code through serializeError and deserializeError. A DOMException and many
    driver errors carry a number there, and it was dropped, even under includeOwnProperties, because
    code is a fixed field read only as a string. SerializedError.code is now string | number; a
    code that is neither a string nor a finite number is still left out. An ExtendedError's own code
    stays a string.

Patch Changes

  • #37 8b0633f Thanks @jonatankruszewski! - describeValue names a function, '[Function: loadUser]', instead of printing its source, and
    describes an object whose JSON is {} by its string tag when that says more: '[object Map]'
    rather than '{}' for a Map, a Set or a RegExp. toError and serializeError use it for a
    thrown value that is not an error, so those messages change the same way.

  • #37 6f75bde Thanks @jonatankruszewski! - Define code and context on an instance only when there is a value. Both were own enumerable
    properties on every instance, so Node's console.log(error) printed
    code: undefined, context: undefined after the stack of every error that had neither. Reading an
    absent one still gives undefined; Object.keys(error) no longer lists it.

ts-extended-errors@0.4.4

Choose a tag to compare

Patch Changes

  • #28 eda94cc Thanks @jonatankruszewski! - Treat getters, proxy traps and prototype checks that throw while inspecting an unknown value as
    unavailable metadata. Serialization, normalization, cause traversal, type guards and
    deserialization now keep handling the original failure; a value that refuses every form of
    inspection is described as '<uninspectable object>'. Exceptions from caller-provided predicates
    and error constructors still propagate.

ts-extended-errors@0.4.3

Choose a tag to compare

Patch Changes

  • #25 1472f5e Thanks @jonatankruszewski! - Describe the package as a zero-dependency error model for TypeScript applications that use native
    exceptions but need typed context, cause-chain inspection, and reliable JSON round trips. Clarify
    how that model differs from typed return values and effect systems, and document the trust,
    redaction and class-name rules at a serialization boundary. The code does not change.

ts-extended-errors@0.4.2

Choose a tag to compare

Patch Changes

  • #23 78935d7 Thanks @jonatankruszewski! - Describe the package as a zero-dependency error model for TypeScript applications that use native exceptions but need typed context, cause-chain inspection, and reliable JSON round trips. The npm description, README and llms.txt summary change; the code does not.

ts-extended-errors@0.4.1

Choose a tag to compare

Patch Changes

  • #21 1b358cf Thanks @jonatankruszewski! - Publish to npm as ts-extended-errors, in place of @rxova/ts-extended-errors on GitHub Packages.

    Install with npm install ts-extended-errors; no .npmrc scope line or GitHub token is needed. Every
    earlier version, 0.1.0 to 0.4.0, is on npm under the new name with the same code. A project on the
    old name changes the dependency and its imports from @rxova/ts-extended-errors to
    ts-extended-errors; nothing else about the API changes. Releases now publish from CI through npm
    trusted publishing, with provenance.

@rxova/ts-extended-errors@0.4.0

Choose a tag to compare

Minor Changes

  • #19 1c3cd65 Thanks @jonatankruszewski! - Type context as present on the instances of a class defined with message, when the throw site has
    to pass one. Fixes #17.

    message makes context a required constructor argument as soon as its type has a required field,
    but the instance type stayed Context | undefined — so every read went through a ?. and a ??
    for a branch that cannot be taken, and the workaround was a hand-written class holding the value as
    its own field, which is the boilerplate message exists to remove.

    const CorruptRecordError = defineError('CorruptRecordError', {
      message: ({ key }: { key: string }) => `unreadable record: ${key}`,
    })
    
    const found = findCauseOf(error, CorruptRecordError)
    found?.context.key // string — was `'context' is possibly 'undefined'`

    The narrowing uses the same condition the constructor already uses to decide whether context is
    required, so a class whose context has no required fields is unchanged: there the options argument
    really is optional and an instance really can have none.

    The (message, options) constructor is the one path that could otherwise build an instance without
    a context, and deserializeError rebuilds through it. It cannot require the argument without the
    class ceasing to be an ErrorClass — which is what lets it be passed in classes and be another
    class's base — so it now defaults context to {}. A payload carrying no context therefore
    rebuilds as context: {} rather than undefined, and error.context.key reads undefined instead
    of throwing.

Patch Changes

  • #18 540e69f Thanks @jonatankruszewski! - Point the tarball's llms.txt and README at the documentation site.

    The package now has docs at https://rxova.org/packages/ts-extended-errors/, built from apps/docs in
    this repository. Both files ship inside the tarball, so an agent that installed the package and read
    node_modules/@rxova/ts-extended-errors/llms.txt had no way to find them.

    llms.txt gains the site, its llms.txt index and its llms-full.txt; the README's "For coding
    agents" section says the same for a reader. Nothing about the API or the published files changes.

@rxova/ts-extended-errors@0.3.0

Choose a tag to compare

Minor Changes

  • #15 a65757e Thanks @jonatankruszewski! - defineError takes a message option, (context) => string, that writes the message from the
    context: new InvalidDateError({ context: { value } }). The type of context comes from its
    parameter or from the type parameter, and is required when it has required fields. A class defined
    on one without its own message writes the message the same way. When message throws, the error
    is still created, with the class name as its message. A string first argument still sets the
    message, which is how deserializeError rebuilds these classes. Classes defined without message
    are unchanged.

@rxova/ts-extended-errors@0.2.1

Choose a tag to compare

Patch Changes

  • #10 97a54de Thanks @jonatankruszewski! - Rewrite the repository README: what the library does with a short example, install, the workspace
    layout, development commands and hooks, contributing and releases.

@rxova/ts-extended-errors@0.2.0

Choose a tag to compare

Minor Changes

  • #8 06c11b0 Thanks @jonatankruszewski! - serializeError writes an AggregateError's errors, each serialized like a cause, and
    deserializeError rebuilds them as an AggregateError. The new maxAggregatedErrors option
    (default 10) caps how many are kept across the whole output, and errorsOmitted counts the rest.

Patch Changes

  • #8 50d0330 Thanks @jonatankruszewski! - serializeError copies context field by field through a JSON round trip instead of returning the
    error's own object. A later change to the error's context no longer changes a serialized copy, a
    redactor editing the output no longer edits the error, and a BigInt in context or in an own
    field is written as '10n' instead of making JSON.stringify throw.