@pellux/goodvibes-errors 0.30.3 → 0.33.0
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 +2 -2
- package/dist/daemon-error-contract.d.ts +13 -13
- package/dist/daemon-error-contract.d.ts.map +1 -1
- package/dist/index.d.ts +71 -35
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +73 -27
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @pellux/goodvibes-errors
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Public GoodVibes error package for structured SDK, transport, and daemon failures.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Most applications should install `@pellux/goodvibes-sdk` and import `@pellux/goodvibes-sdk/errors`. Install this package directly when you only need the shared error model.
|
|
6
6
|
|
|
7
7
|
Consumer import:
|
|
8
8
|
|
|
@@ -19,18 +19,18 @@ export declare const DaemonErrorCategory: {
|
|
|
19
19
|
export type DaemonErrorSource = 'provider' | 'tool' | 'transport' | 'config' | 'permission' | 'runtime' | 'render' | 'acp' | 'unknown';
|
|
20
20
|
export interface StructuredDaemonErrorBody {
|
|
21
21
|
readonly error: string;
|
|
22
|
-
readonly hint?: string;
|
|
23
|
-
readonly code?: string;
|
|
24
|
-
readonly category?: DaemonErrorCategory;
|
|
25
|
-
readonly source?: DaemonErrorSource;
|
|
26
|
-
readonly recoverable?: boolean;
|
|
27
|
-
readonly status?: number;
|
|
28
|
-
readonly provider?: string;
|
|
29
|
-
readonly operation?: string;
|
|
30
|
-
readonly phase?: string;
|
|
31
|
-
readonly requestId?: string;
|
|
32
|
-
readonly providerCode?: string;
|
|
33
|
-
readonly providerType?: string;
|
|
34
|
-
readonly retryAfterMs?: number;
|
|
22
|
+
readonly hint?: string | undefined;
|
|
23
|
+
readonly code?: string | undefined;
|
|
24
|
+
readonly category?: DaemonErrorCategory | undefined;
|
|
25
|
+
readonly source?: DaemonErrorSource | undefined;
|
|
26
|
+
readonly recoverable?: boolean | undefined;
|
|
27
|
+
readonly status?: number | undefined;
|
|
28
|
+
readonly provider?: string | undefined;
|
|
29
|
+
readonly operation?: string | undefined;
|
|
30
|
+
readonly phase?: string | undefined;
|
|
31
|
+
readonly requestId?: string | undefined;
|
|
32
|
+
readonly providerCode?: string | undefined;
|
|
33
|
+
readonly providerType?: string | undefined;
|
|
34
|
+
readonly retryAfterMs?: number | undefined;
|
|
35
35
|
}
|
|
36
36
|
//# sourceMappingURL=daemon-error-contract.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon-error-contract.d.ts","sourceRoot":"","sources":["../src/daemon-error-contract.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAC3B,gBAAgB,GAChB,eAAe,GACf,SAAS,GACT,YAAY,GACZ,SAAS,GACT,SAAS,GACT,aAAa,GACb,WAAW,GACX,YAAY,GACZ,MAAM,GACN,QAAQ,GACR,UAAU,GACV,SAAS,GACT,UAAU,GACV,SAAS,CAAC;AAEd,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;CAgBwB,CAAC;AAEzD,MAAM,MAAM,iBAAiB,GACzB,UAAU,GACV,MAAM,GACN,WAAW,GACX,QAAQ,GACR,YAAY,GACZ,SAAS,GACT,QAAQ,GACR,KAAK,GACL,SAAS,CAAC;AAEd,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"daemon-error-contract.d.ts","sourceRoot":"","sources":["../src/daemon-error-contract.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAC3B,gBAAgB,GAChB,eAAe,GACf,SAAS,GACT,YAAY,GACZ,SAAS,GACT,SAAS,GACT,aAAa,GACb,WAAW,GACX,YAAY,GACZ,MAAM,GACN,QAAQ,GACR,UAAU,GACV,SAAS,GACT,UAAU,GACV,SAAS,CAAC;AAEd,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;CAgBwB,CAAC;AAEzD,MAAM,MAAM,iBAAiB,GACzB,UAAU,GACV,MAAM,GACN,WAAW,GACX,QAAQ,GACR,YAAY,GACZ,SAAS,GACT,QAAQ,GACR,KAAK,GACL,SAAS,CAAC;AAEd,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5C"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type { DaemonErrorCategory, DaemonErrorSource, StructuredDaemonErrorBody } from './daemon-error-contract.js';
|
|
2
2
|
export type { DaemonErrorSource, StructuredDaemonErrorBody, } from './daemon-error-contract.js';
|
|
3
3
|
export { DaemonErrorCategory } from './daemon-error-contract.js';
|
|
4
|
+
/**
|
|
5
|
+
* `'contract'` is an SDK-internal category used when the daemon returns
|
|
6
|
+
* a response that violates the expected contract schema. It is NOT part of the
|
|
7
|
+
* daemon wire schema (`DaemonErrorCategory`) and MUST NOT be marshalled over
|
|
8
|
+
* the wire — doing so will cause the daemon to schema-reject the error envelope.
|
|
9
|
+
* Treat `'contract'` as a local SDK sentinel only.
|
|
10
|
+
*/
|
|
4
11
|
export type ErrorCategory = DaemonErrorCategory | 'contract';
|
|
5
12
|
export type ErrorSource = DaemonErrorSource | 'contract';
|
|
6
13
|
/**
|
|
@@ -18,23 +25,23 @@ export type ErrorSource = DaemonErrorSource | 'contract';
|
|
|
18
25
|
*/
|
|
19
26
|
export type SDKErrorKind = 'auth' | 'config' | 'contract' | 'network' | 'not-found' | 'protocol' | 'rate-limit' | 'service' | 'internal' | 'tool' | 'validation' | 'unknown';
|
|
20
27
|
export interface GoodVibesSdkErrorOptions {
|
|
21
|
-
readonly code?: string;
|
|
22
|
-
readonly category?: ErrorCategory;
|
|
23
|
-
readonly source?: ErrorSource;
|
|
24
|
-
readonly recoverable?: boolean;
|
|
25
|
-
readonly status?: number;
|
|
26
|
-
readonly url?: string;
|
|
27
|
-
readonly method?: string;
|
|
28
|
-
readonly body?: unknown;
|
|
29
|
-
readonly hint?: string;
|
|
30
|
-
readonly provider?: string;
|
|
31
|
-
readonly operation?: string;
|
|
32
|
-
readonly phase?: string;
|
|
33
|
-
readonly requestId?: string;
|
|
34
|
-
readonly providerCode?: string;
|
|
35
|
-
readonly providerType?: string;
|
|
36
|
-
readonly retryAfterMs?: number;
|
|
37
|
-
readonly cause?: unknown;
|
|
28
|
+
readonly code?: string | undefined;
|
|
29
|
+
readonly category?: ErrorCategory | undefined;
|
|
30
|
+
readonly source?: ErrorSource | undefined;
|
|
31
|
+
readonly recoverable?: boolean | undefined;
|
|
32
|
+
readonly status?: number | undefined;
|
|
33
|
+
readonly url?: string | undefined;
|
|
34
|
+
readonly method?: string | undefined;
|
|
35
|
+
readonly body?: unknown | undefined;
|
|
36
|
+
readonly hint?: string | undefined;
|
|
37
|
+
readonly provider?: string | undefined;
|
|
38
|
+
readonly operation?: string | undefined;
|
|
39
|
+
readonly phase?: string | undefined;
|
|
40
|
+
readonly requestId?: string | undefined;
|
|
41
|
+
readonly providerCode?: string | undefined;
|
|
42
|
+
readonly providerType?: string | undefined;
|
|
43
|
+
readonly retryAfterMs?: number | undefined;
|
|
44
|
+
readonly cause?: unknown | undefined;
|
|
38
45
|
}
|
|
39
46
|
export declare const RETRYABLE_STATUS_CODES: readonly number[];
|
|
40
47
|
/**
|
|
@@ -45,7 +52,7 @@ export declare const RETRYABLE_STATUS_CODES: readonly number[];
|
|
|
45
52
|
*
|
|
46
53
|
* ### Narrowing pattern
|
|
47
54
|
* ```ts
|
|
48
|
-
* import { GoodVibesSdkError, HttpStatusError, ConfigurationError } from '@pellux/goodvibes-
|
|
55
|
+
* import { GoodVibesSdkError, HttpStatusError, ConfigurationError } from '@pellux/goodvibes-errors';
|
|
49
56
|
*
|
|
50
57
|
* try {
|
|
51
58
|
* await sdk.operator.agents.list();
|
|
@@ -62,23 +69,23 @@ export declare const RETRYABLE_STATUS_CODES: readonly number[];
|
|
|
62
69
|
*/
|
|
63
70
|
export declare class GoodVibesSdkError extends Error {
|
|
64
71
|
readonly kind: SDKErrorKind;
|
|
65
|
-
readonly code?: string;
|
|
72
|
+
readonly code?: string | undefined;
|
|
66
73
|
readonly category: ErrorCategory;
|
|
67
74
|
readonly source: ErrorSource;
|
|
68
75
|
readonly recoverable: boolean;
|
|
69
|
-
readonly status?: number;
|
|
70
|
-
readonly url?: string;
|
|
71
|
-
readonly method?: string;
|
|
72
|
-
readonly body?: unknown;
|
|
73
|
-
readonly hint?: string;
|
|
74
|
-
readonly provider?: string;
|
|
75
|
-
readonly operation?: string;
|
|
76
|
-
readonly phase?: string;
|
|
77
|
-
readonly requestId?: string;
|
|
78
|
-
readonly providerCode?: string;
|
|
79
|
-
readonly providerType?: string;
|
|
80
|
-
readonly retryAfterMs?: number;
|
|
81
|
-
readonly cause?: unknown;
|
|
76
|
+
readonly status?: number | undefined;
|
|
77
|
+
readonly url?: string | undefined;
|
|
78
|
+
readonly method?: string | undefined;
|
|
79
|
+
readonly body?: unknown | undefined;
|
|
80
|
+
readonly hint?: string | undefined;
|
|
81
|
+
readonly provider?: string | undefined;
|
|
82
|
+
readonly operation?: string | undefined;
|
|
83
|
+
readonly phase?: string | undefined;
|
|
84
|
+
readonly requestId?: string | undefined;
|
|
85
|
+
readonly providerCode?: string | undefined;
|
|
86
|
+
readonly providerType?: string | undefined;
|
|
87
|
+
readonly retryAfterMs?: number | undefined;
|
|
88
|
+
readonly cause?: unknown | undefined;
|
|
82
89
|
static [Symbol.hasInstance](value: unknown): boolean;
|
|
83
90
|
constructor(message: string, options?: GoodVibesSdkErrorOptions);
|
|
84
91
|
toJSON(): Record<string, unknown>;
|
|
@@ -91,7 +98,7 @@ export declare class GoodVibesSdkError extends Error {
|
|
|
91
98
|
* Category: `'config'`. Kind: `'config'`.
|
|
92
99
|
*
|
|
93
100
|
* @example
|
|
94
|
-
* import { ConfigurationError } from '@pellux/goodvibes-
|
|
101
|
+
* import { ConfigurationError } from '@pellux/goodvibes-errors';
|
|
95
102
|
*
|
|
96
103
|
* try {
|
|
97
104
|
* await sdk.auth.setToken('x');
|
|
@@ -102,6 +109,13 @@ export declare class GoodVibesSdkError extends Error {
|
|
|
102
109
|
* }
|
|
103
110
|
*/
|
|
104
111
|
export declare class ConfigurationError extends GoodVibesSdkError {
|
|
112
|
+
/**
|
|
113
|
+
* Brand contract — `code` is the source of truth, not the prototype chain.
|
|
114
|
+
* A `GoodVibesSdkError` constructed directly with `code: 'SDK_CONFIGURATION_ERROR'`
|
|
115
|
+
* will pass `instanceof ConfigurationError` even if its prototype is only
|
|
116
|
+
* `GoodVibesSdkError`. Callers that need strict prototype checking should use
|
|
117
|
+
* `Object.getPrototypeOf(err) === ConfigurationError.prototype` instead.
|
|
118
|
+
*/
|
|
105
119
|
static [Symbol.hasInstance](value: unknown): boolean;
|
|
106
120
|
constructor(message: string, options?: GoodVibesSdkErrorOptions);
|
|
107
121
|
}
|
|
@@ -113,7 +127,7 @@ export declare class ConfigurationError extends GoodVibesSdkError {
|
|
|
113
127
|
* Category: `'contract'`. Kind: `'contract'`.
|
|
114
128
|
*
|
|
115
129
|
* @example
|
|
116
|
-
* import { ContractError } from '@pellux/goodvibes-
|
|
130
|
+
* import { ContractError } from '@pellux/goodvibes-errors';
|
|
117
131
|
*
|
|
118
132
|
* try {
|
|
119
133
|
* const result = await sdk.operator.agents.get({ id: agentId });
|
|
@@ -125,6 +139,13 @@ export declare class ConfigurationError extends GoodVibesSdkError {
|
|
|
125
139
|
* }
|
|
126
140
|
*/
|
|
127
141
|
export declare class ContractError extends GoodVibesSdkError {
|
|
142
|
+
/**
|
|
143
|
+
* Brand contract — `code` is the source of truth, not the prototype chain.
|
|
144
|
+
* A `GoodVibesSdkError` constructed directly with `code: 'SDK_CONTRACT_ERROR'`
|
|
145
|
+
* will pass `instanceof ContractError` even if its prototype is only
|
|
146
|
+
* `GoodVibesSdkError`. Callers that need strict prototype checking should use
|
|
147
|
+
* `Object.getPrototypeOf(err) === ContractError.prototype` instead.
|
|
148
|
+
*/
|
|
128
149
|
static [Symbol.hasInstance](value: unknown): boolean;
|
|
129
150
|
constructor(message: string, options?: GoodVibesSdkErrorOptions);
|
|
130
151
|
}
|
|
@@ -135,12 +156,20 @@ export declare class ContractError extends GoodVibesSdkError {
|
|
|
135
156
|
* - `401` → `'authentication'` `402` → `'billing'` `403` → `'authorization'`
|
|
136
157
|
* - `404` → `'not_found'` `408` → `'timeout'` `429` → `'rate_limit'`
|
|
137
158
|
* - `5xx` → `'service'`
|
|
159
|
+
* - Any other status (or when constructed without a `status`) → `'unknown'`
|
|
160
|
+
*
|
|
161
|
+
* When constructed without a `status` argument (e.g. as a typed
|
|
162
|
+
* wrapper around a structured daemon error that provides its own `category`),
|
|
163
|
+
* the category defaults to `'unknown'`. Callers relying on category-based
|
|
164
|
+
* routing should always prefer the structured-body factory
|
|
165
|
+
* (`createHttpStatusError`) or check `err.category` directly rather than
|
|
166
|
+
* assuming a specific category from constructor arguments alone.
|
|
138
167
|
*
|
|
139
168
|
* Use `recoverable` to decide whether to retry, and `retryAfterMs` for
|
|
140
169
|
* the backoff hint on rate-limit responses.
|
|
141
170
|
*
|
|
142
171
|
* @example
|
|
143
|
-
* import { HttpStatusError } from '@pellux/goodvibes-
|
|
172
|
+
* import { HttpStatusError } from '@pellux/goodvibes-errors';
|
|
144
173
|
*
|
|
145
174
|
* try {
|
|
146
175
|
* await sdk.operator.agents.list();
|
|
@@ -155,6 +184,13 @@ export declare class ContractError extends GoodVibesSdkError {
|
|
|
155
184
|
* }
|
|
156
185
|
*/
|
|
157
186
|
export declare class HttpStatusError extends GoodVibesSdkError {
|
|
187
|
+
/**
|
|
188
|
+
* Brand contract — `code` is the source of truth, not the prototype chain.
|
|
189
|
+
* A `GoodVibesSdkError` constructed directly with `code: 'SDK_HTTP_STATUS_ERROR'`
|
|
190
|
+
* will pass `instanceof HttpStatusError` even if its prototype is only
|
|
191
|
+
* `GoodVibesSdkError`. Callers that need strict prototype checking should use
|
|
192
|
+
* `Object.getPrototypeOf(err) === HttpStatusError.prototype` instead.
|
|
193
|
+
*/
|
|
158
194
|
static [Symbol.hasInstance](value: unknown): boolean;
|
|
159
195
|
constructor(message: string, options?: GoodVibesSdkErrorOptions);
|
|
160
196
|
}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,iBAAiB,EACjB,yBAAyB,EAC1B,MAAM,4BAA4B,CAAC;AAEpC,YAAY,EACV,iBAAiB,EACjB,yBAAyB,GAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,UAAU,CAAC;AAE7D,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,UAAU,CAAC;AAEzD;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,QAAQ,GACR,UAAU,GACV,SAAS,GACT,WAAW,GACX,UAAU,GACV,YAAY,GACZ,SAAS,GACT,UAAU,GACV,MAAM,GACN,YAAY,GACZ,SAAS,CAAC;AAoCd,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -76,7 +76,10 @@ function readErrorCategory(value) {
|
|
|
76
76
|
? value
|
|
77
77
|
: undefined;
|
|
78
78
|
}
|
|
79
|
-
|
|
79
|
+
const MAX_ERROR_CAUSE_DEPTH = 32;
|
|
80
|
+
function inferCategoryFromCause(cause, seen = new Set(), depth = 0) {
|
|
81
|
+
if (depth >= MAX_ERROR_CAUSE_DEPTH)
|
|
82
|
+
return undefined;
|
|
80
83
|
if (!cause || typeof cause !== 'object')
|
|
81
84
|
return undefined;
|
|
82
85
|
const objectCause = cause;
|
|
@@ -87,9 +90,9 @@ function inferCategoryFromCause(cause, seen = new Set()) {
|
|
|
87
90
|
const category = readErrorCategory(record.category);
|
|
88
91
|
if (category && category !== 'unknown')
|
|
89
92
|
return category;
|
|
90
|
-
return inferCategoryFromCause(record.cause, seen)
|
|
91
|
-
?? inferCategoryFromCause(record.originalError, seen)
|
|
92
|
-
?? inferCategoryFromCause(record.error, seen);
|
|
93
|
+
return inferCategoryFromCause(record.cause, seen, depth + 1)
|
|
94
|
+
?? inferCategoryFromCause(record.originalError, seen, depth + 1)
|
|
95
|
+
?? inferCategoryFromCause(record.error, seen, depth + 1);
|
|
93
96
|
}
|
|
94
97
|
/**
|
|
95
98
|
* Base error class for all errors thrown by the GoodVibes SDK.
|
|
@@ -99,7 +102,7 @@ function inferCategoryFromCause(cause, seen = new Set()) {
|
|
|
99
102
|
*
|
|
100
103
|
* ### Narrowing pattern
|
|
101
104
|
* ```ts
|
|
102
|
-
* import { GoodVibesSdkError, HttpStatusError, ConfigurationError } from '@pellux/goodvibes-
|
|
105
|
+
* import { GoodVibesSdkError, HttpStatusError, ConfigurationError } from '@pellux/goodvibes-errors';
|
|
103
106
|
*
|
|
104
107
|
* try {
|
|
105
108
|
* await sdk.operator.agents.list();
|
|
@@ -142,12 +145,7 @@ export class GoodVibesSdkError extends Error {
|
|
|
142
145
|
if (typeof value !== 'object' || value === null)
|
|
143
146
|
return false;
|
|
144
147
|
const record = value;
|
|
145
|
-
return record[GOODVIBES_SDK_ERROR_BRAND] === true
|
|
146
|
-
|| (value instanceof Error
|
|
147
|
-
&& typeof record.kind === 'string'
|
|
148
|
-
&& typeof record.category === 'string'
|
|
149
|
-
&& typeof record.source === 'string'
|
|
150
|
-
&& typeof record.recoverable === 'boolean');
|
|
148
|
+
return record[GOODVIBES_SDK_ERROR_BRAND] === true;
|
|
151
149
|
}
|
|
152
150
|
constructor(message, options = {}) {
|
|
153
151
|
const category = options.category
|
|
@@ -204,14 +202,31 @@ export class GoodVibesSdkError extends Error {
|
|
|
204
202
|
});
|
|
205
203
|
}
|
|
206
204
|
}
|
|
207
|
-
function serializeCause(cause) {
|
|
205
|
+
function serializeCause(cause, seen = new Set(), depth = 0) {
|
|
208
206
|
if (cause === undefined)
|
|
209
207
|
return undefined;
|
|
208
|
+
if (depth >= MAX_ERROR_CAUSE_DEPTH)
|
|
209
|
+
return undefined;
|
|
210
210
|
if (cause instanceof Error) {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
211
|
+
const record = { name: cause.name, message: cause.message };
|
|
212
|
+
// Walk .cause, .originalError, .error chains symmetrically with inferCategoryFromCause.
|
|
213
|
+
const causeRecord = cause;
|
|
214
|
+
const nestedCause = causeRecord.cause ?? causeRecord.originalError ?? causeRecord.error;
|
|
215
|
+
if (nestedCause !== undefined) {
|
|
216
|
+
const objectKey = causeRecord.cause !== undefined ? 'cause' : causeRecord.originalError !== undefined ? 'originalError' : 'error';
|
|
217
|
+
const serialized = typeof nestedCause === 'object' && nestedCause !== null
|
|
218
|
+
? (seen.has(nestedCause) ? '[Circular]' : serializeCause(nestedCause, new Set([...seen, nestedCause]), depth + 1))
|
|
219
|
+
: serializeCause(nestedCause, seen, depth + 1);
|
|
220
|
+
if (serialized !== undefined)
|
|
221
|
+
record[objectKey] = serialized;
|
|
222
|
+
}
|
|
223
|
+
return omitUndefined(record);
|
|
224
|
+
}
|
|
225
|
+
if (typeof cause === 'object' && cause !== null) {
|
|
226
|
+
if (seen.has(cause))
|
|
227
|
+
return '[Circular]';
|
|
228
|
+
// Serialize plain-object causes (e.g. from transport error payloads) as-is.
|
|
229
|
+
return cause;
|
|
215
230
|
}
|
|
216
231
|
return cause;
|
|
217
232
|
}
|
|
@@ -226,7 +241,7 @@ function omitUndefined(record) {
|
|
|
226
241
|
* Category: `'config'`. Kind: `'config'`.
|
|
227
242
|
*
|
|
228
243
|
* @example
|
|
229
|
-
* import { ConfigurationError } from '@pellux/goodvibes-
|
|
244
|
+
* import { ConfigurationError } from '@pellux/goodvibes-errors';
|
|
230
245
|
*
|
|
231
246
|
* try {
|
|
232
247
|
* await sdk.auth.setToken('x');
|
|
@@ -237,14 +252,22 @@ function omitUndefined(record) {
|
|
|
237
252
|
* }
|
|
238
253
|
*/
|
|
239
254
|
export class ConfigurationError extends GoodVibesSdkError {
|
|
255
|
+
/**
|
|
256
|
+
* Brand contract — `code` is the source of truth, not the prototype chain.
|
|
257
|
+
* A `GoodVibesSdkError` constructed directly with `code: 'SDK_CONFIGURATION_ERROR'`
|
|
258
|
+
* will pass `instanceof ConfigurationError` even if its prototype is only
|
|
259
|
+
* `GoodVibesSdkError`. Callers that need strict prototype checking should use
|
|
260
|
+
* `Object.getPrototypeOf(err) === ConfigurationError.prototype` instead.
|
|
261
|
+
*/
|
|
240
262
|
static [Symbol.hasInstance](value) {
|
|
241
263
|
if (this !== ConfigurationError) {
|
|
242
264
|
return typeof value === 'object'
|
|
243
265
|
&& value !== null
|
|
244
266
|
&& this.prototype.isPrototypeOf(value);
|
|
245
267
|
}
|
|
246
|
-
|
|
247
|
-
|
|
268
|
+
// Require both the brand (real SDK error instance) and matching code
|
|
269
|
+
// to prevent plain objects like { code: 'SDK_CONFIGURATION_ERROR' } from passing.
|
|
270
|
+
return GoodVibesSdkError[Symbol.hasInstance](value)
|
|
248
271
|
&& value.code === 'SDK_CONFIGURATION_ERROR';
|
|
249
272
|
}
|
|
250
273
|
constructor(message, options = {}) {
|
|
@@ -265,7 +288,7 @@ export class ConfigurationError extends GoodVibesSdkError {
|
|
|
265
288
|
* Category: `'contract'`. Kind: `'contract'`.
|
|
266
289
|
*
|
|
267
290
|
* @example
|
|
268
|
-
* import { ContractError } from '@pellux/goodvibes-
|
|
291
|
+
* import { ContractError } from '@pellux/goodvibes-errors';
|
|
269
292
|
*
|
|
270
293
|
* try {
|
|
271
294
|
* const result = await sdk.operator.agents.get({ id: agentId });
|
|
@@ -277,14 +300,22 @@ export class ConfigurationError extends GoodVibesSdkError {
|
|
|
277
300
|
* }
|
|
278
301
|
*/
|
|
279
302
|
export class ContractError extends GoodVibesSdkError {
|
|
303
|
+
/**
|
|
304
|
+
* Brand contract — `code` is the source of truth, not the prototype chain.
|
|
305
|
+
* A `GoodVibesSdkError` constructed directly with `code: 'SDK_CONTRACT_ERROR'`
|
|
306
|
+
* will pass `instanceof ContractError` even if its prototype is only
|
|
307
|
+
* `GoodVibesSdkError`. Callers that need strict prototype checking should use
|
|
308
|
+
* `Object.getPrototypeOf(err) === ContractError.prototype` instead.
|
|
309
|
+
*/
|
|
280
310
|
static [Symbol.hasInstance](value) {
|
|
281
311
|
if (this !== ContractError) {
|
|
282
312
|
return typeof value === 'object'
|
|
283
313
|
&& value !== null
|
|
284
314
|
&& this.prototype.isPrototypeOf(value);
|
|
285
315
|
}
|
|
286
|
-
|
|
287
|
-
|
|
316
|
+
// Require both the brand (real SDK error instance) and matching code
|
|
317
|
+
// to prevent plain objects like { code: 'SDK_CONTRACT_ERROR' } from passing.
|
|
318
|
+
return GoodVibesSdkError[Symbol.hasInstance](value)
|
|
288
319
|
&& value.code === 'SDK_CONTRACT_ERROR';
|
|
289
320
|
}
|
|
290
321
|
constructor(message, options = {}) {
|
|
@@ -304,12 +335,20 @@ export class ContractError extends GoodVibesSdkError {
|
|
|
304
335
|
* - `401` → `'authentication'` `402` → `'billing'` `403` → `'authorization'`
|
|
305
336
|
* - `404` → `'not_found'` `408` → `'timeout'` `429` → `'rate_limit'`
|
|
306
337
|
* - `5xx` → `'service'`
|
|
338
|
+
* - Any other status (or when constructed without a `status`) → `'unknown'`
|
|
339
|
+
*
|
|
340
|
+
* When constructed without a `status` argument (e.g. as a typed
|
|
341
|
+
* wrapper around a structured daemon error that provides its own `category`),
|
|
342
|
+
* the category defaults to `'unknown'`. Callers relying on category-based
|
|
343
|
+
* routing should always prefer the structured-body factory
|
|
344
|
+
* (`createHttpStatusError`) or check `err.category` directly rather than
|
|
345
|
+
* assuming a specific category from constructor arguments alone.
|
|
307
346
|
*
|
|
308
347
|
* Use `recoverable` to decide whether to retry, and `retryAfterMs` for
|
|
309
348
|
* the backoff hint on rate-limit responses.
|
|
310
349
|
*
|
|
311
350
|
* @example
|
|
312
|
-
* import { HttpStatusError } from '@pellux/goodvibes-
|
|
351
|
+
* import { HttpStatusError } from '@pellux/goodvibes-errors';
|
|
313
352
|
*
|
|
314
353
|
* try {
|
|
315
354
|
* await sdk.operator.agents.list();
|
|
@@ -324,16 +363,23 @@ export class ContractError extends GoodVibesSdkError {
|
|
|
324
363
|
* }
|
|
325
364
|
*/
|
|
326
365
|
export class HttpStatusError extends GoodVibesSdkError {
|
|
366
|
+
/**
|
|
367
|
+
* Brand contract — `code` is the source of truth, not the prototype chain.
|
|
368
|
+
* A `GoodVibesSdkError` constructed directly with `code: 'SDK_HTTP_STATUS_ERROR'`
|
|
369
|
+
* will pass `instanceof HttpStatusError` even if its prototype is only
|
|
370
|
+
* `GoodVibesSdkError`. Callers that need strict prototype checking should use
|
|
371
|
+
* `Object.getPrototypeOf(err) === HttpStatusError.prototype` instead.
|
|
372
|
+
*/
|
|
327
373
|
static [Symbol.hasInstance](value) {
|
|
328
374
|
if (this !== HttpStatusError) {
|
|
329
375
|
return typeof value === 'object'
|
|
330
376
|
&& value !== null
|
|
331
377
|
&& this.prototype.isPrototypeOf(value);
|
|
332
378
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
379
|
+
// Require both the brand (real SDK error instance) and matching code
|
|
380
|
+
// to prevent plain objects like { code: 'SDK_HTTP_STATUS_ERROR' } from passing.
|
|
381
|
+
return GoodVibesSdkError[Symbol.hasInstance](value)
|
|
382
|
+
&& value.code === 'SDK_HTTP_STATUS_ERROR';
|
|
337
383
|
}
|
|
338
384
|
constructor(message, options = {}) {
|
|
339
385
|
super(message, {
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-errors",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"engines": {
|
|
5
|
-
"
|
|
5
|
+
"bun": "1.3.10",
|
|
6
|
+
"node": ">=22.0.0"
|
|
6
7
|
},
|
|
7
8
|
"description": "Structured SDK, transport, and daemon error types for GoodVibes integrations.",
|
|
8
9
|
"type": "module",
|