@crewhaus/errors 0.1.0 → 0.1.2
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/package.json +5 -10
- package/src/index.test.ts +50 -0
- package/src/index.ts +12 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crewhaus/errors",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Typed error hierarchy shared across factory layers",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"license": "Apache-2.0",
|
|
15
15
|
"author": {
|
|
16
16
|
"name": "Max Meier",
|
|
17
|
-
"email": "max@
|
|
18
|
-
"url": "https://
|
|
17
|
+
"email": "max@crewhaus.ai",
|
|
18
|
+
"url": "https://crewhaus.ai"
|
|
19
19
|
},
|
|
20
20
|
"repository": {
|
|
21
21
|
"type": "git",
|
|
@@ -27,12 +27,7 @@
|
|
|
27
27
|
"url": "https://github.com/crewhaus/factory/issues"
|
|
28
28
|
},
|
|
29
29
|
"publishConfig": {
|
|
30
|
-
"access": "
|
|
30
|
+
"access": "public"
|
|
31
31
|
},
|
|
32
|
-
"files": [
|
|
33
|
-
"src",
|
|
34
|
-
"README.md",
|
|
35
|
-
"LICENSE",
|
|
36
|
-
"NOTICE"
|
|
37
|
-
]
|
|
32
|
+
"files": ["src", "README.md", "LICENSE", "NOTICE"]
|
|
38
33
|
}
|
package/src/index.test.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
import {
|
|
3
|
+
AdapterError,
|
|
3
4
|
CompilerError,
|
|
4
5
|
ConfigError,
|
|
5
6
|
CrewhausError,
|
|
6
7
|
McpConnectionError,
|
|
7
8
|
McpError,
|
|
8
9
|
McpProtocolError,
|
|
10
|
+
ProviderAuthError,
|
|
9
11
|
RuntimeError,
|
|
10
12
|
SpecParseError,
|
|
11
13
|
} from "./index";
|
|
@@ -100,3 +102,51 @@ describe("subclasses", () => {
|
|
|
100
102
|
});
|
|
101
103
|
});
|
|
102
104
|
});
|
|
105
|
+
|
|
106
|
+
describe("AdapterError", () => {
|
|
107
|
+
test("tags itself with the adapter code and captures providerId", () => {
|
|
108
|
+
const err = new AdapterError("openai", "request failed");
|
|
109
|
+
expect(err).toBeInstanceOf(CrewhausError);
|
|
110
|
+
expect(err.code).toBe("adapter");
|
|
111
|
+
expect(err.providerId).toBe("openai");
|
|
112
|
+
expect(err.message).toBe("request failed");
|
|
113
|
+
expect(err.name).toBe("AdapterError");
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test("preserves the underlying SDK error via cause", () => {
|
|
117
|
+
const sdkErr = new Error("429 rate limited");
|
|
118
|
+
const err = new AdapterError("anthropic", "upstream error", sdkErr);
|
|
119
|
+
expect(err.cause).toBe(sdkErr);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test("toJSON serializes the cause chain (providerId is not part of the wire shape)", () => {
|
|
123
|
+
const err = new AdapterError("anthropic", "stream parse failed", new Error("EOF"));
|
|
124
|
+
expect(err.toJSON()).toEqual({
|
|
125
|
+
name: "AdapterError",
|
|
126
|
+
code: "adapter",
|
|
127
|
+
message: "stream parse failed",
|
|
128
|
+
cause: { name: "Error", message: "EOF" },
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
describe("ProviderAuthError", () => {
|
|
134
|
+
test("is an AdapterError with the adapter code and a stable name", () => {
|
|
135
|
+
const err = new ProviderAuthError("openai", "missing OPENAI_API_KEY");
|
|
136
|
+
expect(err).toBeInstanceOf(AdapterError);
|
|
137
|
+
expect(err).toBeInstanceOf(CrewhausError);
|
|
138
|
+
expect(err.code).toBe("adapter");
|
|
139
|
+
expect(err.providerId).toBe("openai");
|
|
140
|
+
expect(err.name).toBe("ProviderAuthError");
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
test("toJSON reports the ProviderAuthError name", () => {
|
|
144
|
+
const err = new ProviderAuthError("anthropic", "invalid credentials");
|
|
145
|
+
expect(err.toJSON()).toEqual({
|
|
146
|
+
name: "ProviderAuthError",
|
|
147
|
+
code: "adapter",
|
|
148
|
+
message: "invalid credentials",
|
|
149
|
+
cause: undefined,
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -87,10 +87,18 @@ export class McpError extends CrewhausError {
|
|
|
87
87
|
|
|
88
88
|
export class McpConnectionError extends McpError {
|
|
89
89
|
override readonly name = "McpConnectionError";
|
|
90
|
+
// biome-ignore lint/complexity/noUselessConstructor: explicit constructor so Bun --coverage counts it as a covered function (field-initializer-only classes can't hit 100% function coverage otherwise)
|
|
91
|
+
constructor(message: string, cause?: unknown) {
|
|
92
|
+
super(message, cause);
|
|
93
|
+
}
|
|
90
94
|
}
|
|
91
95
|
|
|
92
96
|
export class McpProtocolError extends McpError {
|
|
93
97
|
override readonly name = "McpProtocolError";
|
|
98
|
+
// biome-ignore lint/complexity/noUselessConstructor: explicit constructor so Bun --coverage counts it as a covered function (field-initializer-only classes can't hit 100% function coverage otherwise)
|
|
99
|
+
constructor(message: string, cause?: unknown) {
|
|
100
|
+
super(message, cause);
|
|
101
|
+
}
|
|
94
102
|
}
|
|
95
103
|
|
|
96
104
|
/**
|
|
@@ -114,4 +122,8 @@ export class AdapterError extends CrewhausError {
|
|
|
114
122
|
*/
|
|
115
123
|
export class ProviderAuthError extends AdapterError {
|
|
116
124
|
override readonly name = "ProviderAuthError";
|
|
125
|
+
// biome-ignore lint/complexity/noUselessConstructor: explicit constructor so Bun --coverage counts it as a covered function (field-initializer-only classes can't hit 100% function coverage otherwise)
|
|
126
|
+
constructor(providerId: string, message: string, cause?: unknown) {
|
|
127
|
+
super(providerId, message, cause);
|
|
128
|
+
}
|
|
117
129
|
}
|