@pellux/goodvibes-errors 0.18.3
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 +33 -0
- package/dist/daemon-error-contract.d.ts +19 -0
- package/dist/daemon-error-contract.d.ts.map +1 -0
- package/dist/daemon-error-contract.js +1 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +123 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# @pellux/goodvibes-errors
|
|
2
|
+
|
|
3
|
+
Structured GoodVibes SDK error types.
|
|
4
|
+
|
|
5
|
+
Install:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @pellux/goodvibes-errors
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Use this package when you need to branch on:
|
|
12
|
+
- HTTP status
|
|
13
|
+
- error category
|
|
14
|
+
- error source
|
|
15
|
+
- recovery hints
|
|
16
|
+
- request ids
|
|
17
|
+
- retry timing
|
|
18
|
+
|
|
19
|
+
Example:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { HttpStatusError } from '@pellux/goodvibes-errors';
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
// integration code
|
|
26
|
+
} catch (error) {
|
|
27
|
+
if (error instanceof HttpStatusError && error.status === 401) {
|
|
28
|
+
// re-authenticate
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The exported fields are intended to replace fragile message parsing in client and daemon integrations.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type DaemonErrorCategory = 'authentication' | 'authorization' | 'billing' | 'rate_limit' | 'timeout' | 'network' | 'bad_request' | 'not_found' | 'permission' | 'tool' | 'config' | 'protocol' | 'service' | 'internal' | 'unknown';
|
|
2
|
+
export type DaemonErrorSource = 'provider' | 'tool' | 'transport' | 'config' | 'permission' | 'runtime' | 'render' | 'acp' | 'unknown';
|
|
3
|
+
export interface StructuredDaemonErrorBody {
|
|
4
|
+
readonly error: string;
|
|
5
|
+
readonly hint?: string;
|
|
6
|
+
readonly code?: string;
|
|
7
|
+
readonly category?: DaemonErrorCategory;
|
|
8
|
+
readonly source?: DaemonErrorSource;
|
|
9
|
+
readonly recoverable?: boolean;
|
|
10
|
+
readonly status?: number;
|
|
11
|
+
readonly provider?: string;
|
|
12
|
+
readonly operation?: string;
|
|
13
|
+
readonly phase?: string;
|
|
14
|
+
readonly requestId?: string;
|
|
15
|
+
readonly providerCode?: string;
|
|
16
|
+
readonly providerType?: string;
|
|
17
|
+
readonly retryAfterMs?: number;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=daemon-error-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon-error-contract.d.ts","sourceRoot":"","sources":["../src/daemon-error-contract.ts"],"names":[],"mappings":"AACA,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,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;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { DaemonErrorCategory, DaemonErrorSource, StructuredDaemonErrorBody } from './daemon-error-contract.js';
|
|
2
|
+
export type { DaemonErrorCategory, DaemonErrorSource, StructuredDaemonErrorBody, } from './daemon-error-contract.js';
|
|
3
|
+
export type ErrorCategory = DaemonErrorCategory | 'contract';
|
|
4
|
+
export type ErrorSource = DaemonErrorSource | 'contract';
|
|
5
|
+
export interface GoodVibesSdkErrorOptions {
|
|
6
|
+
readonly code?: string;
|
|
7
|
+
readonly category?: ErrorCategory;
|
|
8
|
+
readonly source?: ErrorSource;
|
|
9
|
+
readonly recoverable?: boolean;
|
|
10
|
+
readonly status?: number;
|
|
11
|
+
readonly url?: string;
|
|
12
|
+
readonly method?: string;
|
|
13
|
+
readonly body?: unknown;
|
|
14
|
+
readonly hint?: string;
|
|
15
|
+
readonly provider?: string;
|
|
16
|
+
readonly operation?: string;
|
|
17
|
+
readonly phase?: string;
|
|
18
|
+
readonly requestId?: string;
|
|
19
|
+
readonly providerCode?: string;
|
|
20
|
+
readonly providerType?: string;
|
|
21
|
+
readonly retryAfterMs?: number;
|
|
22
|
+
}
|
|
23
|
+
export declare const RETRYABLE_STATUS_CODES: readonly number[];
|
|
24
|
+
export declare class GoodVibesSdkError extends Error {
|
|
25
|
+
readonly code?: string;
|
|
26
|
+
readonly category: ErrorCategory;
|
|
27
|
+
readonly source: ErrorSource;
|
|
28
|
+
readonly recoverable: boolean;
|
|
29
|
+
readonly status?: number;
|
|
30
|
+
readonly url?: string;
|
|
31
|
+
readonly method?: string;
|
|
32
|
+
readonly body?: unknown;
|
|
33
|
+
readonly hint?: string;
|
|
34
|
+
readonly provider?: string;
|
|
35
|
+
readonly operation?: string;
|
|
36
|
+
readonly phase?: string;
|
|
37
|
+
readonly requestId?: string;
|
|
38
|
+
readonly providerCode?: string;
|
|
39
|
+
readonly providerType?: string;
|
|
40
|
+
readonly retryAfterMs?: number;
|
|
41
|
+
constructor(message: string, options?: GoodVibesSdkErrorOptions);
|
|
42
|
+
}
|
|
43
|
+
export declare class ConfigurationError extends GoodVibesSdkError {
|
|
44
|
+
constructor(message: string, options?: GoodVibesSdkErrorOptions);
|
|
45
|
+
}
|
|
46
|
+
export declare class ContractError extends GoodVibesSdkError {
|
|
47
|
+
constructor(message: string, options?: GoodVibesSdkErrorOptions);
|
|
48
|
+
}
|
|
49
|
+
export declare class HttpStatusError extends GoodVibesSdkError {
|
|
50
|
+
constructor(message: string, options?: GoodVibesSdkErrorOptions);
|
|
51
|
+
}
|
|
52
|
+
export declare function isStructuredDaemonErrorBody(value: unknown): value is StructuredDaemonErrorBody;
|
|
53
|
+
export declare function createHttpStatusError(status: number, url: string, method: string, body: unknown): HttpStatusError;
|
|
54
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
export const RETRYABLE_STATUS_CODES = [408, 429, 500, 502, 503, 504];
|
|
2
|
+
function inferCategory(status) {
|
|
3
|
+
if (status === 400)
|
|
4
|
+
return 'bad_request';
|
|
5
|
+
if (status === 401)
|
|
6
|
+
return 'authentication';
|
|
7
|
+
if (status === 402)
|
|
8
|
+
return 'billing';
|
|
9
|
+
if (status === 403)
|
|
10
|
+
return 'authorization';
|
|
11
|
+
if (status === 404)
|
|
12
|
+
return 'not_found';
|
|
13
|
+
if (status === 408)
|
|
14
|
+
return 'timeout';
|
|
15
|
+
if (status === 429)
|
|
16
|
+
return 'rate_limit';
|
|
17
|
+
if (status !== undefined && status >= 500)
|
|
18
|
+
return 'service';
|
|
19
|
+
return 'unknown';
|
|
20
|
+
}
|
|
21
|
+
export class GoodVibesSdkError extends Error {
|
|
22
|
+
code;
|
|
23
|
+
category;
|
|
24
|
+
source;
|
|
25
|
+
recoverable;
|
|
26
|
+
status;
|
|
27
|
+
url;
|
|
28
|
+
method;
|
|
29
|
+
body;
|
|
30
|
+
hint;
|
|
31
|
+
provider;
|
|
32
|
+
operation;
|
|
33
|
+
phase;
|
|
34
|
+
requestId;
|
|
35
|
+
providerCode;
|
|
36
|
+
providerType;
|
|
37
|
+
retryAfterMs;
|
|
38
|
+
constructor(message, options = {}) {
|
|
39
|
+
super(message);
|
|
40
|
+
this.name = this.constructor.name;
|
|
41
|
+
this.code = options.code;
|
|
42
|
+
this.category = options.category ?? inferCategory(options.status);
|
|
43
|
+
this.source = options.source ?? 'unknown';
|
|
44
|
+
this.recoverable = options.recoverable ?? (options.status !== undefined && RETRYABLE_STATUS_CODES.includes(options.status));
|
|
45
|
+
this.status = options.status;
|
|
46
|
+
this.url = options.url;
|
|
47
|
+
this.method = options.method;
|
|
48
|
+
this.body = options.body;
|
|
49
|
+
this.hint = options.hint;
|
|
50
|
+
this.provider = options.provider;
|
|
51
|
+
this.operation = options.operation;
|
|
52
|
+
this.phase = options.phase;
|
|
53
|
+
this.requestId = options.requestId;
|
|
54
|
+
this.providerCode = options.providerCode;
|
|
55
|
+
this.providerType = options.providerType;
|
|
56
|
+
this.retryAfterMs = options.retryAfterMs;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export class ConfigurationError extends GoodVibesSdkError {
|
|
60
|
+
constructor(message, options = {}) {
|
|
61
|
+
super(message, {
|
|
62
|
+
...options,
|
|
63
|
+
code: options.code ?? 'SDK_CONFIGURATION_ERROR',
|
|
64
|
+
category: 'config',
|
|
65
|
+
source: options.source ?? 'config',
|
|
66
|
+
recoverable: false,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export class ContractError extends GoodVibesSdkError {
|
|
71
|
+
constructor(message, options = {}) {
|
|
72
|
+
super(message, {
|
|
73
|
+
...options,
|
|
74
|
+
code: options.code ?? 'SDK_CONTRACT_ERROR',
|
|
75
|
+
category: 'contract',
|
|
76
|
+
source: options.source ?? 'contract',
|
|
77
|
+
recoverable: false,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export class HttpStatusError extends GoodVibesSdkError {
|
|
82
|
+
constructor(message, options = {}) {
|
|
83
|
+
super(message, {
|
|
84
|
+
...options,
|
|
85
|
+
code: options.code ?? 'SDK_HTTP_STATUS_ERROR',
|
|
86
|
+
source: options.source ?? 'transport',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export function isStructuredDaemonErrorBody(value) {
|
|
91
|
+
return typeof value === 'object' && value !== null && typeof value.error === 'string';
|
|
92
|
+
}
|
|
93
|
+
export function createHttpStatusError(status, url, method, body) {
|
|
94
|
+
if (isStructuredDaemonErrorBody(body)) {
|
|
95
|
+
return new HttpStatusError(body.error, {
|
|
96
|
+
code: body.code,
|
|
97
|
+
category: body.category,
|
|
98
|
+
source: body.source ?? 'transport',
|
|
99
|
+
recoverable: body.recoverable,
|
|
100
|
+
status: body.status ?? status,
|
|
101
|
+
url,
|
|
102
|
+
method,
|
|
103
|
+
body,
|
|
104
|
+
hint: body.hint,
|
|
105
|
+
provider: body.provider,
|
|
106
|
+
operation: body.operation,
|
|
107
|
+
phase: body.phase,
|
|
108
|
+
requestId: body.requestId,
|
|
109
|
+
providerCode: body.providerCode,
|
|
110
|
+
providerType: body.providerType,
|
|
111
|
+
retryAfterMs: body.retryAfterMs,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
const message = typeof body === 'string' && body.trim()
|
|
115
|
+
? body.trim()
|
|
116
|
+
: `Request failed with status ${status}`;
|
|
117
|
+
return new HttpStatusError(message, {
|
|
118
|
+
status,
|
|
119
|
+
url,
|
|
120
|
+
method,
|
|
121
|
+
body,
|
|
122
|
+
});
|
|
123
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pellux/goodvibes-errors",
|
|
3
|
+
"version": "0.18.3",
|
|
4
|
+
"description": "Structured SDK, transport, and daemon error types for GoodVibes integrations.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"sideEffects": false,
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/mgd34msu/goodvibes-sdk.git"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/mgd34msu/goodvibes-sdk/issues"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/mgd34msu/goodvibes-sdk",
|
|
28
|
+
"keywords": [
|
|
29
|
+
"goodvibes",
|
|
30
|
+
"sdk",
|
|
31
|
+
"errors",
|
|
32
|
+
"telemetry",
|
|
33
|
+
"transport"
|
|
34
|
+
],
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
}
|
|
38
|
+
}
|