ferr 2.1.14 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1 +1,195 @@
1
- ferr
1
+ # ferr
2
+
3
+ `ferr` is a pragmatic error library for TypeScript/Node.
4
+ `fErr` stands for "Fancy Error".
5
+
6
+ It keeps the native `Error` model (`instanceof Error` still works), while making failures easier to compose, enrich, and log in real systems.
7
+
8
+ ## The spirit
9
+
10
+ Most production errors are not one event. They are a chain:
11
+
12
+ - low-level failure (`cause`)
13
+ - service-level context (`op`, `code`, `context`)
14
+ - user-facing intent (`clientMsg`)
15
+ - breadcrumbs (`notes`)
16
+
17
+ `ferr` is built for that chain.
18
+
19
+ The goal is not "fancy exceptions." The goal is readable, mergeable, diagnosable errors that survive multiple layers without losing meaning.
20
+
21
+ ## Install
22
+
23
+ ```bash
24
+ pnpm add ferr
25
+ ```
26
+
27
+ ## Quick start
28
+
29
+ ```ts
30
+ import { FErr } from 'ferr'
31
+
32
+ const err = new FErr({
33
+ op: 'loadUser',
34
+ code: 'USER_NOT_FOUND',
35
+ message: 'User lookup failed',
36
+ clientMsg: 'Unable to load account right now',
37
+ context: { userId: 'u_123' },
38
+ cause: new Error('db timeout')
39
+ })
40
+
41
+ console.log(err.toMessageString())
42
+ console.log(err.toDetailedString())
43
+ ```
44
+
45
+ ## Examples
46
+
47
+ 1. Normalize unknown caught errors
48
+
49
+ ```ts
50
+ import { FErr } from 'ferr'
51
+
52
+ try {
53
+ await doWork()
54
+ } catch (e) {
55
+ throw FErr.from(e)
56
+ .withOp('service.doWork')
57
+ .withCode('WORK_FAILED')
58
+ .withContext({ jobId: 'j_123' })
59
+ }
60
+ ```
61
+
62
+ 2. Add context without mutation
63
+
64
+ ```ts
65
+ import { FErr } from 'ferr'
66
+
67
+ const base = new FErr({ op: 'auth.login', message: 'Login failed' })
68
+ const enriched = base
69
+ .withContext({ requestId: 'r_123', tenantId: 't_9' })
70
+ .withNotes('retry path used')
71
+
72
+ // base is unchanged; enriched is a new instance
73
+ ```
74
+
75
+ 3. Merge failures across boundaries
76
+
77
+ ```ts
78
+ import { FErr } from 'ferr'
79
+
80
+ const appErr = new FErr({ op: 'createOrder', message: 'Order failed' })
81
+ const merged = appErr.mergeAppend(externalErr)
82
+ console.log(merged.toDetailedString())
83
+ ```
84
+
85
+ 4. Throw helpers for guard clauses
86
+
87
+ ```ts
88
+ import { rethrowFerr, throwFerr, throwIfUndefined } from 'ferr'
89
+
90
+ throwFerr({
91
+ with: {
92
+ op: 'authorize',
93
+ message: 'Unauthorized',
94
+ context: { userId }
95
+ }
96
+ })
97
+
98
+ try {
99
+ await doWork()
100
+ } catch (e) {
101
+ rethrowFerr(e, {
102
+ with: { op: 'api.handleRequest', code: 'REQUEST_FAILED', message: 'Request failed' }
103
+ })
104
+ }
105
+
106
+ throwIfUndefined(config, 'boot', 'Missing config')
107
+ ```
108
+
109
+ 5. Wrapper-style throw/rethrow (recommended for service layers)
110
+
111
+ ```ts
112
+ import { rethrowFerr, throwFerr } from 'ferr'
113
+
114
+ const authorize = (userId: string) => {
115
+ if (!userId) {
116
+ throwFerr({
117
+ with: {
118
+ op: 'auth.authorize',
119
+ code: 'AUTH_MISSING_USER',
120
+ message: 'Missing user id'
121
+ }
122
+ })
123
+ }
124
+ }
125
+
126
+ const handleRequest = async () => {
127
+ try {
128
+ await authorize('u_123')
129
+ } catch (caught) {
130
+ rethrowFerr(caught, {
131
+ with: {
132
+ op: 'api.handleRequest',
133
+ code: 'REQUEST_FAILED',
134
+ message: 'Request failed'
135
+ }
136
+ })
137
+ }
138
+ }
139
+ ```
140
+
141
+ ## API overview
142
+
143
+ ### `FErr`
144
+
145
+ - `new FErr(options)`
146
+ - `FErr.from(input, overrides?)`
147
+ - `FErr.is(value)`
148
+ - `mergeAppend(...)`, `mergeUpdate(...)`
149
+ - `withMessage/withOp/withCode/withClientMsg/withContext/withCause/withNotes`
150
+ - `toMessageString()`, `toDetailedString()`
151
+ - `toOptions()`, `toJSON()`
152
+
153
+ ### Throw/rethrow helpers
154
+
155
+ - `throwFerr`, `throwFerrIf`
156
+ - `rethrowFerr`
157
+ - `throwErr`, `throwErrIf`
158
+ - `rethrowAppend`, `rethrowUpdate`
159
+ - `throwIfUndefined`
160
+ - custom factories: `createThrowErr`, `createThrowErrIf`, `createThrowIfUndefined`
161
+
162
+ Note: root package exports are intentionally limited to the `FErr` API and throw/rethrow helpers.
163
+ Internal utility helpers are implementation details and are not part of the stable public API contract.
164
+
165
+ ## Why this over plain `Error`?
166
+
167
+ Plain `Error` is good for simple throw/catch, but it does not define how to:
168
+
169
+ - carry structured runtime context
170
+ - merge error information from multiple layers
171
+ - keep short and detailed formats in sync
172
+ - coerce arbitrary thrown values consistently
173
+
174
+ `ferr` gives those patterns first-class APIs.
175
+
176
+ ## Runtime compatibility
177
+
178
+ - Node-first package
179
+ - ESM/CJS build outputs
180
+ - Works with standard `try/catch`
181
+ - `FErr` remains `instanceof Error`
182
+
183
+ ## Development
184
+
185
+ ```bash
186
+ pnpm lint
187
+ pnpm sanity
188
+ pnpm run viz
189
+ ```
190
+
191
+ ## Release (Local)
192
+
193
+ ```bash
194
+ pnpm run release
195
+ ```
package/dist/index.cjs ADDED
@@ -0,0 +1,7 @@
1
+ 'use strict';var F=n=>(...t)=>!n(...t),J=n=>Array.isArray(n)?n:[n];var G=(n,t)=>Array.isArray(t)&&!t.some(r=>!n(r)),R=n=>G(t=>typeof t=="string",n),W=F(R);function g(n="",t=" "){return R(n)?n.map(r=>`${t}${r}`):typeof n=="string"?`${t}${n}`:n}var N=(n,t="",r="")=>{let e=J(n);return W(e)?t:e.reduce((c,o,u)=>`${c}${r}${o}${u<e.length-1?`
2
+ `:""}`,t)},T=n=>n.split(`
3
+ `).map(t=>t.trim()).slice(1);var K=n=>typeof n=="object"&&n!==null&&Object.getPrototypeOf(n)===Object.prototype,k=(n,t)=>{if(n===void 0)return "undefined";if(typeof n=="bigint")return `${n.toString()}n`;if(typeof n=="symbol")return n.toString();if(typeof n=="function")return `[Function ${n.name||"anonymous"}]`;if(n===null||typeof n!="object")return n;if(t.has(n))return "[Circular]";if(t.add(n),Array.isArray(n))return n.map(e=>k(e,t));if(K(n)){let e={};return Object.entries(n).forEach(([c,o])=>{e[c]=k(o,t);}),e}let r={_type:n.constructor?.name||"Object"};return Object.entries(n).forEach(([e,c])=>{r[e]=k(c,t);}),r},l=n=>{try{return n===void 0?"undefined":JSON.stringify(k(n,new WeakSet),null,2)}catch{return "[Unserializable]"}};var p="unknown error",y=n=>typeof n=="object"&&n!==null&&!Array.isArray(n),s=n=>typeof n=="string",Q=n=>s(n)&&n.length>0,i=n=>n==null,I=n=>y(n)&&Object.getPrototypeOf(n)===Object.prototype,P=n=>i(n)?[]:Array.isArray(n)?n.filter(s):s(n)?[n]:[],h=n=>Array.isArray(n)?n.filter(s):s(n)?T(n):[],j=n=>Array.isArray(n)?n.filter(s):[],$=(n,t)=>!s(t)||t.length===0||n.includes(t)?n:[...n,t],X=(n,t)=>{let r=[];return n.forEach(e=>{r.includes(e)||r.push(e);}),t.forEach(e=>{r.includes(e)||r.push(e);}),r},Y=n=>i(n)?null:n instanceof Error||s(n)||y(n)?n:{value:n},A=n=>n!==p,O=n=>s(n)?n:n instanceof Error?n.message||p:y(n)&&s(n.message)?n.message:null,Z=n=>{if(n instanceof a)return n.toOptions();if(s(n))return {message:n};if(n instanceof Error)return {message:n.message||p,cause:n};if(!y(n))return {};let t={};return s(n.message)&&(t.message=n.message),s(n.op)&&(t.op=n.op),Array.isArray(n.opTrace)&&(t.opTrace=j(n.opTrace)),s(n.code)&&(t.code=n.code),s(n.clientMsg)&&(t.clientMsg=n.clientMsg),i(n.context)||(t.context=n.context),(Array.isArray(n.notes)||s(n.notes))&&(t.notes=n.notes),i(n.cause)||(t.cause=n.cause),i(t.cause)&&!i(n.externalExp)&&(t.cause=n.externalExp),Array.isArray(n.stackLines)?t.stackLines=h(n.stackLines):Array.isArray(n.stackArr)?t.stackLines=h(n.stackArr):s(n.stack)&&(t.stackLines=h(n.stack)),t},V=(n,t)=>!i(n)&&!i(t)&&I(n)&&I(t)?{...t,...n}:i(n)?t:n,U=(n,t)=>{let r=[...n.notes],e=w=>{r.includes(w)||r.push(w);},c=n.code;t.code&&(c?e(`Code: ${t.code}`):c=t.code);let o=n.op;t.op&&(o||(o=t.op));let u=n.message,E=t.message;A(E)&&(A(u)?e(E):u=E);let d=n.clientMsg;t.clientMsg&&(d?e(t.clientMsg):d=t.clientMsg),t.notes.forEach(e);let m=n.cause;if(!i(t.cause))if(i(m))m=t.cause;else {let w=O(t.cause);w&&e(w);}return new a({op:o,opTrace:X(n.opTrace,t.opTrace),code:c,message:u,clientMsg:d,notes:r,context:V(n.context,t.context),cause:m,stackLines:n.stackLines})},a=class n extends Error{op;opTrace;code;clientMsg;notes;context;cause;stackLines;constructor(t={}){let r=Q(t.message)?t.message:p;super(r,i(t.cause)?void 0:{cause:t.cause}),this.name="FErr",Object.defineProperty(this,"message",{value:r,enumerable:true,writable:false,configurable:true}),this.op=s(t.op)?t.op:"",this.opTrace=$(j(t.opTrace),this.op),this.code=s(t.code)?t.code:"",this.clientMsg=s(t.clientMsg)?t.clientMsg:"",this.notes=P(t.notes),this.context=i(t.context)?null:t.context,this.cause=Y(t.cause),this.stackLines=h(t.stackLines).length>0?h(t.stackLines):h(this.stack),Object.setPrototypeOf(this,new.target.prototype);}static is(t){return t instanceof n}static from(t,r={}){if(t instanceof n)return new n({...t.toOptions(),...r,notes:i(r.notes)?t.notes:r.notes,stackLines:h(r.stackLines).length>0?r.stackLines:t.stackLines});let e=Z(t),c={...e,...r,notes:i(r.notes)?e.notes:r.notes,stackLines:h(r.stackLines).length>0?r.stackLines:e.stackLines},o=new n(c),u=O(o.cause);return u?A(o.message)?o.message!==u?o.withNotes(u):o:o.withMessage(u):o}static mergeAppend(t,r){return U(n.from(t),n.from(r))}static mergeUpdate(t,r){return U(n.from(r),n.from(t))}get externalExp(){return this.cause}getCauseMessage(){return O(this.cause)}toOptions(){return {op:this.op,opTrace:[...this.opTrace],code:this.code,message:this.message,clientMsg:this.clientMsg,notes:[...this.notes],context:this.context,cause:this.cause,stackLines:[...this.stackLines]}}toJSON(){return {name:this.name,op:this.op,opTrace:[...this.opTrace],code:this.code,message:this.message,clientMsg:this.clientMsg,notes:[...this.notes],context:this.context,cause:this.cause,stackLines:[...this.stackLines]}}with(t){return new n({...this.toOptions(),...t,notes:i(t.notes)?this.notes:t.notes,stackLines:h(t.stackLines).length>0?t.stackLines:this.stackLines})}withMessage(t){return this.with({message:t})}withOp(t){return this.with({op:t,opTrace:$(this.opTrace,t)})}withCode(t){return this.with({code:t})}withClientMsg(t){return this.with({clientMsg:t})}withContext(t){return this.with({context:t})}withCause(t){return this.with({cause:t})}withNotes(t,r="append"){let e=P(t),c=r==="prepend"?[...e,...this.notes]:[...this.notes,...e];return this.with({notes:c})}toMessageString(){return `${this.op?`${this.op} - `:""}${this.message}`}toDetailedString(){let t=[`
4
+ ERROR encountered !!`];return t.push(g(`Msg: ${this.toMessageString()}`)),this.opTrace.length>0&&(t.push("Operations:"),this.opTrace.forEach(r=>t.push(g(r)))),this.clientMsg&&t.push(g(`Client msg: ${this.clientMsg}`)),this.code&&t.push(g(`Code: ${this.code}`)),this.notes.length>0&&(t.push("Notes:"),this.notes.forEach(r=>t.push(g(r)))),i(this.context)||(t.push("Context:"),l(this.context).split(`
5
+ `).forEach(r=>t.push(g(r)))),t.push("Call Stack:"),this.stackLines.forEach(r=>t.push(g(r))),i(this.cause)||(t.push("Cause:"),this.cause instanceof Error?(t.push(g(`Name: ${this.cause.name}`)),t.push(g(`Message: ${this.cause.message}`)),s(this.cause.stack)&&(t.push("Cause callstack:"),T(this.cause.stack).forEach(r=>t.push(g(r))))):t.push(g(l(this.cause)))),N(t)}mergeAppend(t){return n.mergeAppend(this,t)}mergeUpdate(t){return n.mergeUpdate(this,t)}rethrowAppend(t){throw this.mergeAppend(t)}rethrowUpdate(t){throw this.mergeUpdate(t)}},_=a.is,v=n=>!a.is(n),nn=n=>a.from(n).stackLines;var tn=n=>Array.isArray(n)&&n.every(t=>typeof t=="string"),C=n=>typeof n=="string"?[n]:tn(n)?n:[],q=(n,t)=>{let r=[...C(n),...C(t)];return [...new Set(r)]},rn=n=>!!n&&typeof n=="object"&&"with"in n&&typeof n.with?.op=="string"&&typeof n.with?.message=="string",en=(n,t={})=>({message:n,op:t.op,code:t.code,clientMsg:t.clientMsg,context:t.context,cause:t.cause,notes:t.notes}),D=(n,t,r)=>{let e=[`${n} failed: ${t}`];return r!==void 0&&e.push(`Context: ${l(r)}`),e.join(`
6
+ `)},L=(n,t)=>{if(rn(n)){let r=n.with,e=q(r.notes,n.notes);throw a.from({...r,notes:e})}throw a.from(n,t)},sn=(n,t,r)=>{n&&L(t,r);},b=(n,t,r={})=>L(en(t,{...r,op:n})),on=(n,t,r,e={})=>{n&&b(t,r,e);},cn=(n,t)=>{throw a.from(n).mergeAppend(t)},an=(n,t)=>{throw a.from(n).mergeUpdate(t)},gn=(n,t)=>{let r={...t.with||{},notes:q(t.with?.notes,t.notes)};throw t.mode==="append"?a.from(n).mergeAppend(r):a.from(n).mergeUpdate(r)};function un(n,t,r=p,e={}){n===void 0&&b(t,r,e);}var M=n=>(t,r,e={})=>{throw new n(D(t,r,e.context))},hn=n=>{let t=M(n);return (r,e,c,o={})=>{r&&t(e,c,o);}},pn=n=>{let t=M(n);return (r,e,c=p,o={})=>{r===void 0&&t(e,c,o);}};exports.DEFAULT_FERR_MESSAGE=p;exports.FErr=a;exports.createThrowErr=M;exports.createThrowErrIf=hn;exports.createThrowIfUndefined=pn;exports.formatMsg=D;exports.getStackLines=nn;exports.isFerr=_;exports.isNotFerr=v;exports.rethrowAppend=cn;exports.rethrowFerr=gn;exports.rethrowUpdate=an;exports.throwErr=b;exports.throwErrIf=on;exports.throwFerr=L;exports.throwFerrIf=sn;exports.throwIfUndefined=un;//# sourceMappingURL=index.cjs.map
7
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ferrUtils.ts","../src/fErr.ts","../src/errorUtils.ts"],"names":["complement","pred","args","arrayify","input","isArrayOf","typeCheckPred","array","v","isStringArray","isNotStringArray","tab","tabMe","str","msgListToStr","msgList","appendTo","pre","strings","acc","cur","i","stackStrToArr","stackStr","s","isPlainObject","normalizeContext","value","seen","out","k","toJson","DEFAULT_FERR_MESSAGE","isRecord","isString","isNonEmptyString","isNil","toNoteList","notes","toStackLines","toOpTrace","appendUnique","list","maybeValue","mergeOperations","left","right","op","normalizeCause","nonDefaultMessage","message","messageFromCause","normalizeOptionsFromUnknown","FErr","mergeContext","preferred","secondary","mergeAppend","noteList","addNote","note","code","secondaryMessage","clientMsg","cause","secondaryCauseMessage","_FErr","options","overrides","base","merged","ferr","incomingMessage","primary","existing","incoming","patch","context","position","next","lines","line","isFerr","isNotFerr","getStackLines","item","toNotes","mergeNotes","a","b","isThrowFerrRequest","toFerrOptions","formatMsg","throwFerr","withPatch","throwFerrIf","condition","throwErr","throwErrIf","rethrowAppend","rethrowUpdate","rethrowFerr","caught","throwIfUndefined","createThrowErr","ErrorClass","createThrowErrIf","throwFn","createThrowIfUndefined"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Consolidated utility helpers used across ferr internals and tests.\n */\n\ntype AnyFn = (...args: any[]) => any\n\nexport const curryLast = (fn: AnyFn): any => {\n function curried(this: unknown, ...args: unknown[]) {\n if (args.length >= fn.length) return fn.apply(this, args as any[])\n return (...rest: unknown[]) => curried.apply(this, [...args, ...rest])\n }\n\n return curried\n}\n\nconst hasOwn = (obj: any, propName: string) =>\n obj !== null &&\n obj !== undefined &&\n Object.prototype.hasOwnProperty.call(obj, propName)\n\nconst getProp = (obj: any, propName: string) =>\n obj === null || obj === undefined ? undefined : obj[propName]\n\nconst complement = (pred: (...args: any[]) => boolean) =>\n (...args: any[]) => !pred(...args)\n\n/**\n * Wrap any value as an array.\n */\nexport const arrayify = <T>(input: T | T[]): T[] => Array.isArray(input) ? input : [input]\n/**\n * Deep-flatten value(s) into a one-dimensional array.\n */\nexport const flatArrayify = (input: unknown): unknown[] => arrayify(input as unknown | unknown[]).flat(Infinity) as unknown[]\n\n// if toCheck is an array, return first element, otherwise return toCheck\nexport const headOrReflect = <T>(toCheck: T | T[]): T =>\n Array.isArray(toCheck) ? toCheck[0] : toCheck\n\nexport const doesNotHave = (propName: string, obj: unknown): boolean => !hasOwn(obj, propName)\n\nexport const isNonEmptyString = (toCheck: unknown): toCheck is string => typeof toCheck === 'string' && toCheck.length > 0\nexport const isNotNonEmptyString = complement(isNonEmptyString)\nexport const propIsNonEmptyString = curryLast((propName: string, obj: unknown): boolean => isNonEmptyString(getProp(obj, propName)))\n\nexport const isNonEmptyArray = <T>(toCheck: T[] | unknown): toCheck is T[] => Array.isArray(toCheck) && toCheck.length > 0\nexport const propIsNonEmptyArray = curryLast((propName: string, obj: unknown): boolean => isNonEmptyArray(getProp(obj, propName)))\n\nexport const propIsNotNil = curryLast((propName: string, obj: unknown): boolean => getProp(obj, propName) !== undefined && getProp(obj, propName) !== null)\n\nexport const isNotObjectOrNonEmptyString = (toCheck: unknown): boolean =>\n (typeof toCheck !== 'object' || toCheck === null || Array.isArray(toCheck)) && isNotNonEmptyString(toCheck)\n\nexport const stackStrToStackArr = (stackStr: string): string[] =>\n // drop error message and this call from stack list\n stackStr.split('\\n').map((s: string) => s.trim()).slice(2)\n\nexport const retThrownErr = (fxnThatThrows: (...args: any[]) => unknown, ...argsForFxnThatThrows: any[]): unknown => {\n try { fxnThatThrows(...argsForFxnThatThrows); return null } catch (e) { return e }\n}\n\nexport const reflect = <T>(a: T): T => a\n\nexport const applyAsync = (acc: Promise<any>, val: (x: any) => any): Promise<any> => acc.then(val)\n\n// handles pipeline of any combination of sync and asyn functions\n// Always returns a promise, even if all fxns are async\n// This allows .catch to be used in all pipelines\nexport const fPipe = (...funcs: any[]) => (x?: any) => funcs.reduce(applyAsync, Promise.resolve(x))\n\nexport const copyProp = (propName: string, sourceObj: Record<string, unknown> = {}, targetObj: Record<string, unknown> = {}): Record<string, unknown> =>\n hasOwn(sourceObj, propName) ? { ...targetObj, [propName]: sourceObj[propName] } : targetObj\n\nexport const plainObject = (classInstance: object): object => Object.assign({}, classInstance)\n\n// Given the predicate fxn `checkPred`, check that all elements of `array` pass\n// ((a->bool), a) -> boolean\nexport const isArrayOf = <T>(typeCheckPred: (value: unknown) => value is T, array: unknown): array is T[] =>\n Array.isArray(array) && !array.some(v => !typeCheckPred(v))\n\nexport const isStringArray = (array: unknown): array is string[] => isArrayOf((v: unknown): v is string => typeof v === 'string', array)\nexport const isNotStringArray = complement(isStringArray)\n\nconst isNilOrEmpty = (toCheck: unknown): boolean =>\n toCheck === undefined ||\n toCheck === null ||\n (typeof toCheck === 'string' && toCheck.length === 0) ||\n (Array.isArray(toCheck) && toCheck.length === 0) ||\n (typeof toCheck === 'object' && !Array.isArray(toCheck) && Object.keys(toCheck).length === 0)\n\nexport const propIsNilOrEmpty = (propName: string, obj: unknown): boolean => isNilOrEmpty(getProp(obj, propName))\nexport const propIsNotNilOrEmpty = complement(propIsNilOrEmpty)\n\nexport const addPropIfMissingOrEq = (propName: string, valToCheckAtainst: unknown, newPropVal: unknown, obj: Record<string, unknown>): boolean => {\n if (doesNotHave(propName, obj) || getProp(obj, propName) === valToCheckAtainst) {\n obj[propName] = newPropVal\n return true\n }\n return false\n}\n\n// given a string or array of strings, prepended with the specified tab\n// (['']|'', '') -> [''] | ''\nexport function tab(tabMe: string, tab?: string): string\nexport function tab(tabMe: string[], tab?: string): string[]\nexport function tab(tabMe: any = '', tab = ' ') {\n if (isStringArray(tabMe)) return tabMe.map((str: string) => `${tab}${str}`)\n else if (typeof tabMe === 'string') return `${tab}${tabMe}`\n else return tabMe\n}\n\nexport const msgListToStr = (msgList: string | string[], appendTo = '', pre = ''): string => {\n const strings = arrayify(msgList)\n if (isNotStringArray(strings)) return appendTo\n return strings.reduce((acc: string, cur: string, i: number) =>\n `${acc}${pre}${cur}${i < strings.length - 1 ? '\\n' : ''}`, appendTo)\n}\n\nexport const stackStrToArr = (stackStr: string): string[] =>\n // drop error message from stack list\n stackStr.split('\\n').map((s: string) => s.trim()).slice(1)\n\nexport const stackArrToStr = (msg: string, stackArr: string[]): string =>\n msgListToStr(stackArr, `Error: ${msg}\\n`, ' ')\n\nconst isPlainObject = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' &&\n v !== null &&\n Object.getPrototypeOf(v) === Object.prototype\n\nconst normalizeContext = (value: unknown, seen: WeakSet<object>): unknown => {\n if (value === undefined) return 'undefined'\n if (typeof value === 'bigint') return `${value.toString()}n`\n if (typeof value === 'symbol') return value.toString()\n if (typeof value === 'function') return `[Function ${value.name || 'anonymous'}]`\n if (value === null || typeof value !== 'object') return value\n\n if (seen.has(value)) return '[Circular]'\n seen.add(value)\n\n if (Array.isArray(value))\n return value.map(v => normalizeContext(v, seen))\n\n if (isPlainObject(value)) {\n const out: Record<string, unknown> = {}\n Object.entries(value).forEach(([k, v]) => {\n out[k] = normalizeContext(v, seen)\n })\n return out\n }\n\n const out: Record<string, unknown> = { _type: value.constructor?.name || 'Object' }\n Object.entries(value).forEach(([k, v]) => {\n out[k] = normalizeContext(v, seen)\n })\n return out\n}\n\nexport const toJson = (value: unknown): string => {\n try {\n if (value === undefined) return 'undefined'\n return JSON.stringify(normalizeContext(value, new WeakSet<object>()), null, 2)\n } catch {\n return '[Unserializable]'\n }\n}\n","import { msgListToStr, stackStrToArr, tab, toJson } from './ferrUtils'\n\n/**\n * Default message used when no explicit message can be derived.\n */\nexport const DEFAULT_FERR_MESSAGE = 'unknown error'\n\n/**\n * Accepted input for note updates.\n */\nexport type FErrNotesInput = string | string[]\n/**\n * Canonical cause payload supported by {@link FErr}.\n * - `Error`: structured runtime errors\n * - `string`: lightweight cause message\n * - `Record<string, unknown>`: structured metadata\n * - `null`: no cause\n */\nexport type FErrCause = Error | string | Record<string, unknown> | null\n\n/**\n * Construction options for {@link FErr}.\n *\n * All fields are optional and have safe defaults.\n * `stackLines` is primarily for deterministic tests or custom formatting flows.\n */\nexport interface FErrOptions {\n message?: string\n op?: string\n opTrace?: string[]\n code?: string\n clientMsg?: string\n notes?: FErrNotesInput\n context?: unknown\n cause?: FErrCause | unknown\n stackLines?: string[]\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst isString = (value: unknown): value is string => typeof value === 'string'\n\nconst isNonEmptyString = (value: unknown): value is string => isString(value) && value.length > 0\n\nconst isNil = (value: unknown): value is null | undefined => value === null || value === undefined\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n isRecord(value) && Object.getPrototypeOf(value) === Object.prototype\n\nconst toNoteList = (notes: FErrNotesInput | undefined): string[] => {\n if (isNil(notes)) return []\n if (Array.isArray(notes)) return notes.filter(isString)\n if (isString(notes)) return [notes]\n return []\n}\n\nconst toStackLines = (value: unknown): string[] => {\n if (Array.isArray(value)) return value.filter(isString)\n if (isString(value)) return stackStrToArr(value)\n return []\n}\n\nconst toOpTrace = (value: unknown): string[] =>\n Array.isArray(value) ? value.filter(isString) : []\n\nconst appendUnique = (list: string[], maybeValue: unknown): string[] => {\n if (!isString(maybeValue) || maybeValue.length === 0) return list\n return list.includes(maybeValue) ? list : [...list, maybeValue]\n}\n\nconst mergeOperations = (left: string[], right: string[]): string[] => {\n const out: string[] = []\n left.forEach(op => {\n if (!out.includes(op)) out.push(op)\n })\n right.forEach(op => {\n if (!out.includes(op)) out.push(op)\n })\n return out\n}\n\nconst normalizeCause = (value: unknown): FErrCause => {\n if (isNil(value)) return null\n if (value instanceof Error || isString(value)) return value\n if (isRecord(value)) return value\n return { value }\n}\n\nconst nonDefaultMessage = (message: string): boolean => message !== DEFAULT_FERR_MESSAGE\n\nconst messageFromCause = (input: FErrCause): string | null => {\n if (isString(input)) return input\n if (input instanceof Error) return input.message || DEFAULT_FERR_MESSAGE\n if (isRecord(input) && isString(input.message)) return input.message\n return null\n}\n\nconst normalizeOptionsFromUnknown = (input: unknown): FErrOptions => {\n if (input instanceof FErr) return input.toOptions()\n if (isString(input)) return { message: input }\n\n if (input instanceof Error)\n return {\n message: input.message || DEFAULT_FERR_MESSAGE,\n cause: input\n }\n\n if (!isRecord(input)) return {}\n\n const out: FErrOptions = {}\n if (isString(input.message)) out.message = input.message\n if (isString(input.op)) out.op = input.op\n if (Array.isArray(input.opTrace)) out.opTrace = toOpTrace(input.opTrace)\n if (isString(input.code)) out.code = input.code\n if (isString(input.clientMsg)) out.clientMsg = input.clientMsg\n if (!isNil(input.context)) out.context = input.context\n\n if (Array.isArray(input.notes) || isString(input.notes))\n out.notes = input.notes as FErrNotesInput\n\n if (!isNil(input.cause)) out.cause = input.cause\n // transitional support for older naming in incoming objects\n if (isNil(out.cause) && !isNil(input.externalExp)) out.cause = input.externalExp\n\n if (Array.isArray(input.stackLines)) out.stackLines = toStackLines(input.stackLines)\n else if (Array.isArray(input.stackArr)) out.stackLines = toStackLines(input.stackArr)\n else if (isString(input.stack)) out.stackLines = toStackLines(input.stack)\n\n return out\n}\n\nconst mergeContext = (preferred: unknown, secondary: unknown): unknown => {\n if (!isNil(preferred) && !isNil(secondary) && isPlainObject(preferred) && isPlainObject(secondary))\n return { ...secondary, ...preferred }\n\n return !isNil(preferred) ? preferred : secondary\n}\n\nconst mergeAppend = (preferred: FErr, secondary: FErr): FErr => {\n const noteList: string[] = [...preferred.notes]\n const addNote = (note: string): void => {\n if (!noteList.includes(note)) noteList.push(note)\n }\n\n let code = preferred.code\n if (secondary.code) {\n if (code) addNote(`Code: ${secondary.code}`)\n else code = secondary.code\n }\n\n let op = preferred.op\n if (secondary.op) {\n if (!op) op = secondary.op\n }\n\n let message = preferred.message\n const secondaryMessage = secondary.message\n if (nonDefaultMessage(secondaryMessage)) {\n if (nonDefaultMessage(message)) addNote(secondaryMessage)\n else message = secondaryMessage\n }\n\n let clientMsg = preferred.clientMsg\n if (secondary.clientMsg) {\n if (clientMsg) addNote(secondary.clientMsg)\n else clientMsg = secondary.clientMsg\n }\n\n secondary.notes.forEach(addNote)\n\n let cause: FErrCause = preferred.cause\n if (!isNil(secondary.cause)) {\n if (isNil(cause)) cause = secondary.cause\n else {\n const secondaryCauseMessage = messageFromCause(secondary.cause)\n if (secondaryCauseMessage) addNote(secondaryCauseMessage)\n }\n }\n\n return new FErr({\n op,\n opTrace: mergeOperations(preferred.opTrace, secondary.opTrace),\n code,\n message,\n clientMsg,\n notes: noteList,\n context: mergeContext(preferred.context, secondary.context),\n cause,\n stackLines: preferred.stackLines\n })\n}\n\nexport class FErr extends Error {\n readonly op: string\n readonly opTrace: string[]\n readonly code: string\n readonly clientMsg: string\n readonly notes: string[]\n readonly context: unknown\n override readonly cause: FErrCause\n readonly stackLines: string[]\n\n /**\n * Create a strongly-typed `Error` with operational context.\n *\n * Constructor input is object-based (not positional) so callers can provide\n * only the fields they have without brittle argument ordering.\n */\n constructor(options: FErrOptions = {}) {\n const message = isNonEmptyString(options.message) ? options.message : DEFAULT_FERR_MESSAGE\n super(message, isNil(options.cause) ? undefined : { cause: options.cause })\n this.name = 'FErr'\n\n Object.defineProperty(this, 'message', {\n value: message,\n enumerable: true,\n writable: false,\n configurable: true\n })\n\n this.op = isString(options.op) ? options.op : ''\n this.opTrace = appendUnique(toOpTrace(options.opTrace), this.op)\n this.code = isString(options.code) ? options.code : ''\n this.clientMsg = isString(options.clientMsg) ? options.clientMsg : ''\n this.notes = toNoteList(options.notes)\n this.context = isNil(options.context) ? null : options.context\n this.cause = normalizeCause(options.cause)\n\n this.stackLines =\n toStackLines(options.stackLines).length > 0 ? toStackLines(options.stackLines) :\n toStackLines(this.stack)\n\n Object.setPrototypeOf(this, new.target.prototype)\n }\n\n /**\n * Runtime type guard.\n */\n static is(value: unknown): value is FErr {\n return value instanceof FErr\n }\n\n /**\n * Coerce unknown input into `FErr`.\n *\n * Supported input:\n * - `FErr` (cloned, optionally patched)\n * - `Error`\n * - `string` message\n * - plain object with ferr-like keys\n * - anything else (safe defaults)\n *\n * Message/cause rules:\n * - If message is default and cause has a message/string, adopt cause message.\n * - If message is non-default and cause has a different message/string, append to notes.\n * - Raw string causes are intentionally supported.\n */\n static from(input: unknown, overrides: Partial<FErrOptions> = {}): FErr {\n if (input instanceof FErr) {\n return new FErr({\n ...input.toOptions(),\n ...overrides,\n notes: !isNil(overrides.notes) ? overrides.notes : input.notes,\n stackLines: toStackLines(overrides.stackLines).length > 0 ? overrides.stackLines : input.stackLines\n })\n }\n\n const base = normalizeOptionsFromUnknown(input)\n const merged: FErrOptions = {\n ...base,\n ...overrides,\n notes: !isNil(overrides.notes) ? overrides.notes : base.notes,\n stackLines: toStackLines(overrides.stackLines).length > 0 ? overrides.stackLines : base.stackLines\n }\n\n const ferr = new FErr(merged)\n const incomingMessage = messageFromCause(ferr.cause)\n if (!incomingMessage) return ferr\n\n if (!nonDefaultMessage(ferr.message))\n return ferr.withMessage(incomingMessage)\n\n if (ferr.message !== incomingMessage)\n return ferr.withNotes(incomingMessage)\n\n return ferr\n }\n\n /**\n * Merge with append precedence (primary wins conflicts).\n * Conflicting secondary fields are preserved in notes.\n */\n static mergeAppend(primary: unknown, secondary: unknown): FErr {\n return mergeAppend(FErr.from(primary), FErr.from(secondary))\n }\n\n /**\n * Merge with update precedence (incoming wins conflicts).\n * Equivalent to mergeAppend with argument order swapped.\n */\n static mergeUpdate(existing: unknown, incoming: unknown): FErr {\n return mergeAppend(FErr.from(incoming), FErr.from(existing))\n }\n\n /** @deprecated Use `cause` instead. */\n get externalExp(): FErrCause {\n return this.cause\n }\n\n /**\n * Get a message-like string from cause when available.\n */\n getCauseMessage(): string | null {\n return messageFromCause(this.cause)\n }\n\n /**\n * Export normalized instance fields for cloning/patching.\n */\n toOptions(): FErrOptions {\n return {\n op: this.op,\n opTrace: [...this.opTrace],\n code: this.code,\n message: this.message,\n clientMsg: this.clientMsg,\n notes: [...this.notes],\n context: this.context,\n cause: this.cause,\n stackLines: [...this.stackLines]\n }\n }\n\n /**\n * Export a plain JSON-friendly object.\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n op: this.op,\n opTrace: [...this.opTrace],\n code: this.code,\n message: this.message,\n clientMsg: this.clientMsg,\n notes: [...this.notes],\n context: this.context,\n cause: this.cause,\n stackLines: [...this.stackLines]\n }\n }\n\n /**\n * Immutable patch operation.\n */\n with(patch: Partial<FErrOptions>): FErr {\n return new FErr({\n ...this.toOptions(),\n ...patch,\n notes: !isNil(patch.notes) ? patch.notes : this.notes,\n stackLines: toStackLines(patch.stackLines).length > 0 ? patch.stackLines : this.stackLines\n })\n }\n\n /** Return a copy with updated `message`. */\n withMessage(message: string): FErr {\n return this.with({ message })\n }\n\n /** Return a copy with updated `op`. */\n withOp(op: string): FErr {\n return this.with({\n op,\n opTrace: appendUnique(this.opTrace, op)\n })\n }\n\n /** Return a copy with updated `code`. */\n withCode(code: string): FErr {\n return this.with({ code })\n }\n\n /** Return a copy with updated `clientMsg`. */\n withClientMsg(clientMsg: string): FErr {\n return this.with({ clientMsg })\n }\n\n /** Return a copy with updated `context`. */\n withContext(context: unknown): FErr {\n return this.with({ context })\n }\n\n /** Return a copy with updated `cause`. */\n withCause(cause: unknown): FErr {\n return this.with({ cause })\n }\n\n /**\n * Return a copy with notes appended or prepended.\n */\n withNotes(notes: FErrNotesInput, position: 'append' | 'prepend' = 'append'): FErr {\n const incoming = toNoteList(notes)\n const next = position === 'prepend' ? [...incoming, ...this.notes] : [...this.notes, ...incoming]\n return this.with({ notes: next })\n }\n\n /**\n * Short one-line message, suitable for logs and metrics tags.\n */\n toMessageString(): string {\n return `${this.op ? `${this.op} - ` : ''}${this.message}`\n }\n\n /**\n * Full multi-line human-readable diagnostic block.\n *\n * Includes message metadata, notes, context, stack and cause details.\n */\n toDetailedString(): string {\n const lines = ['\\nERROR encountered !!']\n lines.push(tab(`Msg: ${this.toMessageString()}`) as string)\n\n if (this.opTrace.length > 0) {\n lines.push('Operations:')\n this.opTrace.forEach(op => lines.push(tab(op) as string))\n }\n\n if (this.clientMsg) lines.push(tab(`Client msg: ${this.clientMsg}`) as string)\n if (this.code) lines.push(tab(`Code: ${this.code}`) as string)\n\n if (this.notes.length > 0) {\n lines.push('Notes:')\n this.notes.forEach(note => lines.push(tab(note) as string))\n }\n\n if (!isNil(this.context)) {\n lines.push('Context:')\n toJson(this.context).split('\\n').forEach(line => lines.push(tab(line) as string))\n }\n\n lines.push('Call Stack:')\n this.stackLines.forEach(line => lines.push(tab(line) as string))\n\n if (!isNil(this.cause)) {\n lines.push('Cause:')\n if (this.cause instanceof Error) {\n lines.push(tab(`Name: ${this.cause.name}`) as string)\n lines.push(tab(`Message: ${this.cause.message}`) as string)\n if (isString(this.cause.stack)) {\n lines.push('Cause callstack:')\n stackStrToArr(this.cause.stack).forEach((line: string) => lines.push(tab(line) as string))\n }\n } else {\n lines.push(tab(toJson(this.cause)) as string)\n }\n }\n\n return msgListToStr(lines)\n }\n\n /**\n * Instance wrapper for append-style merge.\n */\n mergeAppend(incoming: unknown): FErr {\n return FErr.mergeAppend(this, incoming)\n }\n\n /**\n * Instance wrapper for update-style merge.\n */\n mergeUpdate(incoming: unknown): FErr {\n return FErr.mergeUpdate(this, incoming)\n }\n\n /**\n * Throw merged error using append precedence.\n */\n rethrowAppend(incoming: unknown): never {\n throw this.mergeAppend(incoming)\n }\n\n /**\n * Throw merged error using update precedence.\n */\n rethrowUpdate(incoming: unknown): never {\n throw this.mergeUpdate(incoming)\n }\n}\n\n/** Convenience alias for {@link FErr.is}. */\nexport const isFerr = FErr.is\n/** Negated convenience check for {@link FErr.is}. */\nexport const isNotFerr = (value: unknown): boolean => !FErr.is(value)\n/**\n * Read normalized stack lines for unknown input via `FErr.from`.\n */\nexport const getStackLines = (value: unknown): string[] => FErr.from(value).stackLines\n","import { DEFAULT_FERR_MESSAGE, FErr, type FErrCause, type FErrOptions } from './fErr'\nimport { toJson } from './ferrUtils'\n\n/**\n * Shared options for throw helper APIs.\n * Mirrors a focused subset of {@link FErrOptions} but keeps callsites ergonomic.\n */\nexport interface ThrowOptions {\n op?: string\n code?: string\n clientMsg?: string\n context?: unknown\n cause?: FErrCause | unknown\n notes?: string | string[]\n}\n\n/**\n * Wrapper-style payload for `throwFerr({ with: ... })`.\n * `op` and `message` are required in this shape.\n */\nexport interface ThrowFerrRequest {\n with: Required<Pick<FErrOptions, 'op' | 'message'>> & Partial<FErrOptions>\n notes?: string | string[]\n}\n\n/**\n * Wrapper-style payload for `rethrowFerr(err, { with: ... })`.\n * Defaults to `update` mode.\n */\nexport interface RethrowFerrRequest {\n with?: Partial<FErrOptions>\n notes?: string | string[]\n mode?: 'update' | 'append'\n}\n\nconst isStringArray = (v: unknown): v is string[] =>\n Array.isArray(v) && v.every(item => typeof item === 'string')\n\nconst toNotes = (notes: unknown): string[] =>\n typeof notes === 'string' ? [notes] :\n isStringArray(notes) ? notes :\n []\n\nconst mergeNotes = (a: unknown, b: unknown): string[] => {\n const merged = [...toNotes(a), ...toNotes(b)]\n return [...new Set(merged)]\n}\n\nconst isThrowFerrRequest = (input: unknown): input is ThrowFerrRequest =>\n !!input &&\n typeof input === 'object' &&\n 'with' in input &&\n typeof (input as { with?: { op?: unknown, message?: unknown } }).with?.op === 'string' &&\n typeof (input as { with?: { op?: unknown, message?: unknown } }).with?.message === 'string'\n\nconst toFerrOptions = (message: string, options: ThrowOptions = {}): FErrOptions => ({\n message,\n op: options.op,\n code: options.code,\n clientMsg: options.clientMsg,\n context: options.context,\n cause: options.cause,\n notes: options.notes\n})\n\n/**\n * Build a readable operation-scoped message.\n * Useful for non-`FErr` custom throw factories.\n */\nexport const formatMsg = (op: string, message: string, context?: unknown): string => {\n const lines = [`${op} failed: ${message}`]\n if (context !== undefined) lines.push(`Context: ${toJson(context)}`)\n return lines.join('\\n')\n}\n\n/**\n * Throw an `FErr` from unknown input.\n */\nexport const throwFerr = (input: unknown, overrides?: Partial<FErrOptions>): never => {\n if (isThrowFerrRequest(input)) {\n const withPatch = input.with\n const notes = mergeNotes(withPatch.notes, input.notes)\n throw FErr.from({\n ...withPatch,\n notes\n })\n }\n\n throw FErr.from(input, overrides)\n}\n\n/**\n * Conditional variant of {@link throwFerr}.\n */\nexport const throwFerrIf = (condition: boolean, input: unknown, overrides?: Partial<FErrOptions>): void => {\n if (condition) throwFerr(input, overrides)\n}\n\n/**\n * Throw an `FErr` from operation + message inputs.\n */\nexport const throwErr = (\n op: string,\n message: string,\n options: ThrowOptions = {}\n): never => {\n return throwFerr(toFerrOptions(message, { ...options, op }))\n}\n\n/**\n * Conditional variant of {@link throwErr}.\n */\nexport const throwErrIf = (\n condition: boolean,\n op: string,\n message: string,\n options: ThrowOptions = {}\n): void => {\n if (condition) throwErr(op, message, options)\n}\n\n/**\n * Re-throw by append-merging incoming error data into an existing error.\n */\nexport const rethrowAppend = (existing: unknown, incoming: unknown): never => {\n throw FErr.from(existing).mergeAppend(incoming)\n}\n\n/**\n * Re-throw by update-merging incoming error data over an existing error.\n */\nexport const rethrowUpdate = (existing: unknown, incoming: unknown): never => {\n throw FErr.from(existing).mergeUpdate(incoming)\n}\n\n/**\n * Wrapper-style rethrow helper.\n *\n * Defaults to update semantics:\n * `rethrowFerr(err, { with: { op, code, ... } })`\n */\nexport const rethrowFerr = (caught: unknown, options: RethrowFerrRequest): never => {\n const patch: Partial<FErrOptions> = {\n ...(options.with || {}),\n notes: mergeNotes(options.with?.notes, options.notes)\n }\n\n if (options.mode === 'append')\n throw FErr.from(caught).mergeAppend(patch)\n\n throw FErr.from(caught).mergeUpdate(patch)\n}\n\n/**\n * Assert that a value is defined; throw `FErr` if not.\n */\nexport function throwIfUndefined<T>(\n value: T,\n op: string,\n message = DEFAULT_FERR_MESSAGE,\n options: ThrowOptions = {}\n): asserts value is Exclude<T, undefined> {\n if (value === undefined) throwErr(op, message, options)\n}\n\n/**\n * Create a formatter-backed throw helper for a custom `Error` class.\n */\nexport const createThrowErr = <E extends Error>(\n ErrorClass: new (message: string) => E\n) => (\n op: string,\n message: string,\n options: ThrowOptions = {}\n ): never => {\n throw new ErrorClass(formatMsg(op, message, options.context))\n }\n\n/**\n * Conditional variant factory of {@link createThrowErr}.\n */\nexport const createThrowErrIf = <E extends Error>(\n ErrorClass: new (message: string) => E\n) => {\n const throwFn = createThrowErr(ErrorClass)\n return (\n condition: boolean,\n op: string,\n message: string,\n options: ThrowOptions = {}\n ): void => {\n if (condition) throwFn(op, message, options)\n }\n}\n\n/**\n * Create a typed `undefined` assertion helper for a custom `Error` class.\n */\nexport const createThrowIfUndefined = <E extends Error>(\n ErrorClass: new (message: string) => E\n) => {\n const throwFn = createThrowErr(ErrorClass)\n return <T>(\n value: T,\n op: string,\n message = DEFAULT_FERR_MESSAGE,\n options: ThrowOptions = {}\n ): asserts value is Exclude<T, undefined> => {\n if (value === undefined) throwFn(op, message, options)\n }\n}\n"]}
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Default message used when no explicit message can be derived.
3
+ */
4
+ declare const DEFAULT_FERR_MESSAGE = "unknown error";
5
+ /**
6
+ * Accepted input for note updates.
7
+ */
8
+ type FErrNotesInput = string | string[];
9
+ /**
10
+ * Canonical cause payload supported by {@link FErr}.
11
+ * - `Error`: structured runtime errors
12
+ * - `string`: lightweight cause message
13
+ * - `Record<string, unknown>`: structured metadata
14
+ * - `null`: no cause
15
+ */
16
+ type FErrCause = Error | string | Record<string, unknown> | null;
17
+ /**
18
+ * Construction options for {@link FErr}.
19
+ *
20
+ * All fields are optional and have safe defaults.
21
+ * `stackLines` is primarily for deterministic tests or custom formatting flows.
22
+ */
23
+ interface FErrOptions {
24
+ message?: string;
25
+ op?: string;
26
+ opTrace?: string[];
27
+ code?: string;
28
+ clientMsg?: string;
29
+ notes?: FErrNotesInput;
30
+ context?: unknown;
31
+ cause?: FErrCause | unknown;
32
+ stackLines?: string[];
33
+ }
34
+ declare class FErr extends Error {
35
+ readonly op: string;
36
+ readonly opTrace: string[];
37
+ readonly code: string;
38
+ readonly clientMsg: string;
39
+ readonly notes: string[];
40
+ readonly context: unknown;
41
+ readonly cause: FErrCause;
42
+ readonly stackLines: string[];
43
+ /**
44
+ * Create a strongly-typed `Error` with operational context.
45
+ *
46
+ * Constructor input is object-based (not positional) so callers can provide
47
+ * only the fields they have without brittle argument ordering.
48
+ */
49
+ constructor(options?: FErrOptions);
50
+ /**
51
+ * Runtime type guard.
52
+ */
53
+ static is(value: unknown): value is FErr;
54
+ /**
55
+ * Coerce unknown input into `FErr`.
56
+ *
57
+ * Supported input:
58
+ * - `FErr` (cloned, optionally patched)
59
+ * - `Error`
60
+ * - `string` message
61
+ * - plain object with ferr-like keys
62
+ * - anything else (safe defaults)
63
+ *
64
+ * Message/cause rules:
65
+ * - If message is default and cause has a message/string, adopt cause message.
66
+ * - If message is non-default and cause has a different message/string, append to notes.
67
+ * - Raw string causes are intentionally supported.
68
+ */
69
+ static from(input: unknown, overrides?: Partial<FErrOptions>): FErr;
70
+ /**
71
+ * Merge with append precedence (primary wins conflicts).
72
+ * Conflicting secondary fields are preserved in notes.
73
+ */
74
+ static mergeAppend(primary: unknown, secondary: unknown): FErr;
75
+ /**
76
+ * Merge with update precedence (incoming wins conflicts).
77
+ * Equivalent to mergeAppend with argument order swapped.
78
+ */
79
+ static mergeUpdate(existing: unknown, incoming: unknown): FErr;
80
+ /** @deprecated Use `cause` instead. */
81
+ get externalExp(): FErrCause;
82
+ /**
83
+ * Get a message-like string from cause when available.
84
+ */
85
+ getCauseMessage(): string | null;
86
+ /**
87
+ * Export normalized instance fields for cloning/patching.
88
+ */
89
+ toOptions(): FErrOptions;
90
+ /**
91
+ * Export a plain JSON-friendly object.
92
+ */
93
+ toJSON(): Record<string, unknown>;
94
+ /**
95
+ * Immutable patch operation.
96
+ */
97
+ with(patch: Partial<FErrOptions>): FErr;
98
+ /** Return a copy with updated `message`. */
99
+ withMessage(message: string): FErr;
100
+ /** Return a copy with updated `op`. */
101
+ withOp(op: string): FErr;
102
+ /** Return a copy with updated `code`. */
103
+ withCode(code: string): FErr;
104
+ /** Return a copy with updated `clientMsg`. */
105
+ withClientMsg(clientMsg: string): FErr;
106
+ /** Return a copy with updated `context`. */
107
+ withContext(context: unknown): FErr;
108
+ /** Return a copy with updated `cause`. */
109
+ withCause(cause: unknown): FErr;
110
+ /**
111
+ * Return a copy with notes appended or prepended.
112
+ */
113
+ withNotes(notes: FErrNotesInput, position?: 'append' | 'prepend'): FErr;
114
+ /**
115
+ * Short one-line message, suitable for logs and metrics tags.
116
+ */
117
+ toMessageString(): string;
118
+ /**
119
+ * Full multi-line human-readable diagnostic block.
120
+ *
121
+ * Includes message metadata, notes, context, stack and cause details.
122
+ */
123
+ toDetailedString(): string;
124
+ /**
125
+ * Instance wrapper for append-style merge.
126
+ */
127
+ mergeAppend(incoming: unknown): FErr;
128
+ /**
129
+ * Instance wrapper for update-style merge.
130
+ */
131
+ mergeUpdate(incoming: unknown): FErr;
132
+ /**
133
+ * Throw merged error using append precedence.
134
+ */
135
+ rethrowAppend(incoming: unknown): never;
136
+ /**
137
+ * Throw merged error using update precedence.
138
+ */
139
+ rethrowUpdate(incoming: unknown): never;
140
+ }
141
+ /** Convenience alias for {@link FErr.is}. */
142
+ declare const isFerr: typeof FErr.is;
143
+ /** Negated convenience check for {@link FErr.is}. */
144
+ declare const isNotFerr: (value: unknown) => boolean;
145
+ /**
146
+ * Read normalized stack lines for unknown input via `FErr.from`.
147
+ */
148
+ declare const getStackLines: (value: unknown) => string[];
149
+
150
+ /**
151
+ * Shared options for throw helper APIs.
152
+ * Mirrors a focused subset of {@link FErrOptions} but keeps callsites ergonomic.
153
+ */
154
+ interface ThrowOptions {
155
+ op?: string;
156
+ code?: string;
157
+ clientMsg?: string;
158
+ context?: unknown;
159
+ cause?: FErrCause | unknown;
160
+ notes?: string | string[];
161
+ }
162
+ /**
163
+ * Wrapper-style payload for `throwFerr({ with: ... })`.
164
+ * `op` and `message` are required in this shape.
165
+ */
166
+ interface ThrowFerrRequest {
167
+ with: Required<Pick<FErrOptions, 'op' | 'message'>> & Partial<FErrOptions>;
168
+ notes?: string | string[];
169
+ }
170
+ /**
171
+ * Wrapper-style payload for `rethrowFerr(err, { with: ... })`.
172
+ * Defaults to `update` mode.
173
+ */
174
+ interface RethrowFerrRequest {
175
+ with?: Partial<FErrOptions>;
176
+ notes?: string | string[];
177
+ mode?: 'update' | 'append';
178
+ }
179
+ /**
180
+ * Build a readable operation-scoped message.
181
+ * Useful for non-`FErr` custom throw factories.
182
+ */
183
+ declare const formatMsg: (op: string, message: string, context?: unknown) => string;
184
+ /**
185
+ * Throw an `FErr` from unknown input.
186
+ */
187
+ declare const throwFerr: (input: unknown, overrides?: Partial<FErrOptions>) => never;
188
+ /**
189
+ * Conditional variant of {@link throwFerr}.
190
+ */
191
+ declare const throwFerrIf: (condition: boolean, input: unknown, overrides?: Partial<FErrOptions>) => void;
192
+ /**
193
+ * Throw an `FErr` from operation + message inputs.
194
+ */
195
+ declare const throwErr: (op: string, message: string, options?: ThrowOptions) => never;
196
+ /**
197
+ * Conditional variant of {@link throwErr}.
198
+ */
199
+ declare const throwErrIf: (condition: boolean, op: string, message: string, options?: ThrowOptions) => void;
200
+ /**
201
+ * Re-throw by append-merging incoming error data into an existing error.
202
+ */
203
+ declare const rethrowAppend: (existing: unknown, incoming: unknown) => never;
204
+ /**
205
+ * Re-throw by update-merging incoming error data over an existing error.
206
+ */
207
+ declare const rethrowUpdate: (existing: unknown, incoming: unknown) => never;
208
+ /**
209
+ * Wrapper-style rethrow helper.
210
+ *
211
+ * Defaults to update semantics:
212
+ * `rethrowFerr(err, { with: { op, code, ... } })`
213
+ */
214
+ declare const rethrowFerr: (caught: unknown, options: RethrowFerrRequest) => never;
215
+ /**
216
+ * Assert that a value is defined; throw `FErr` if not.
217
+ */
218
+ declare function throwIfUndefined<T>(value: T, op: string, message?: string, options?: ThrowOptions): asserts value is Exclude<T, undefined>;
219
+ /**
220
+ * Create a formatter-backed throw helper for a custom `Error` class.
221
+ */
222
+ declare const createThrowErr: <E extends Error>(ErrorClass: new (message: string) => E) => (op: string, message: string, options?: ThrowOptions) => never;
223
+ /**
224
+ * Conditional variant factory of {@link createThrowErr}.
225
+ */
226
+ declare const createThrowErrIf: <E extends Error>(ErrorClass: new (message: string) => E) => (condition: boolean, op: string, message: string, options?: ThrowOptions) => void;
227
+ /**
228
+ * Create a typed `undefined` assertion helper for a custom `Error` class.
229
+ */
230
+ declare const createThrowIfUndefined: <E extends Error>(ErrorClass: new (message: string) => E) => <T>(value: T, op: string, message?: string, options?: ThrowOptions) => asserts value is Exclude<T, undefined>;
231
+
232
+ export { DEFAULT_FERR_MESSAGE, FErr, type FErrCause, type FErrNotesInput, type FErrOptions, type RethrowFerrRequest, type ThrowFerrRequest, type ThrowOptions, createThrowErr, createThrowErrIf, createThrowIfUndefined, formatMsg, getStackLines, isFerr, isNotFerr, rethrowAppend, rethrowFerr, rethrowUpdate, throwErr, throwErrIf, throwFerr, throwFerrIf, throwIfUndefined };