ts-extended-errors@1.0.0
Major Changes
-
#37
aa60b07Thanks @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
1a1eef0Thanks @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,describeValueand the exported types. From here, a breaking change to any of them,
to the serialized shape, or to the defaults oftoJSONandserializeErrormeans a new major.What 1.0 settles on purpose:
JSON.stringify(error)includesstackby default and is meant for
logs, withincludeStack: falsefor anything client-facing; a thrown value that is not an error
serializes undername: typeof value; and cause chains are linear, followingcauseand never an
AggregateError'serrors.
Minor Changes
-
#37
9b8d427Thanks @jonatankruszewski! - Accept any object type as acontexttype, aninterfaceincluded. TheContexttype parameters of
ExtendedError,defineErrorand the exported constructor types were constrained to
Readonly<Record<string, unknown>>, which aninterfacefails for lack of an index signature, so
defineError<UserContext>(…)was a type error wheneverUserContextwas declared withinterface.
The constraint is nowobject;ErrorContextstays the default. -
#37
5e77158Thanks @jonatankruszewski! - Typecodeas the literal a class declares.defineError('NotFoundError', { code: 'HTTP_NOT_FOUND' })
now typescodeas'HTTP_NOT_FOUND'on the class and on its instances, and a class defined without
one is typed with its base's, so aswitchover a taxonomy's codes can be exhaustive and a
findCausepredicate can narrow on one.ExtendedErrorConstructor,MessageErrorConstructorand
DefineErrorOptionsgain aCodetype parameter after their existing ones, andErrorCode, its
constraint, is exported.Two consequences. Naming
Contextas a type argument leavescodeatstring | undefined, because
TypeScript infers all of a call's type arguments or none; nameCodeas well,
defineError<Context, 'X'>(…), to keep the literal. And a class-syntax subclass of adefineError
class can no longer declare a different staticcode, since its instance type already carries the
base's literal; define the leaf withdefineErrorand extend that. -
#37
51303b3Thanks @jonatankruszewski! - Keep a numericcodethroughserializeErroranddeserializeError. ADOMExceptionand many
driver errors carry a number there, and it was dropped, even underincludeOwnProperties, because
codeis a fixed field read only as a string.SerializedError.codeis nowstring | number; a
code that is neither a string nor a finite number is still left out. AnExtendedError's owncode
stays a string.
Patch Changes
-
#37
8b0633fThanks @jonatankruszewski! -describeValuenames 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 aMap, aSetor aRegExp.toErrorandserializeErroruse it for a
thrown value that is not an error, so those messages change the same way. -
#37
6f75bdeThanks @jonatankruszewski! - Definecodeandcontexton an instance only when there is a value. Both were own enumerable
properties on every instance, so Node'sconsole.log(error)printed
code: undefined, context: undefinedafter the stack of every error that had neither. Reading an
absent one still givesundefined;Object.keys(error)no longer lists it.