@crewhaus/errors 0.1.1 → 0.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewhaus/errors",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
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@studiomax.io",
18
- "url": "https://studiomax.io"
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": "restricted"
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.d.ts ADDED
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Typed error hierarchy for factory.
3
+ * Catalog F-foundations (`error-types`) — every later layer imports this
4
+ * for structured error reporting instead of throwing raw `Error`s.
5
+ *
6
+ * Each error carries a stable `code` for programmatic dispatch and serializes
7
+ * its full cause chain via `toJSON()` for the logging layer.
8
+ */
9
+ export type ErrorCode = "spec_parse" | "compiler" | "runtime" | "config" | "tool" | "mcp" | "adapter" | "channel";
10
+ export type SerializedError = {
11
+ name: string;
12
+ code: ErrorCode;
13
+ message: string;
14
+ cause?: SerializedError | {
15
+ name?: string;
16
+ message: string;
17
+ };
18
+ };
19
+ export declare class CrewhausError extends Error {
20
+ readonly name: string;
21
+ readonly code: ErrorCode;
22
+ constructor(code: ErrorCode, message: string, cause?: unknown);
23
+ toJSON(): SerializedError;
24
+ }
25
+ export declare class SpecParseError extends CrewhausError {
26
+ readonly name = "SpecParseError";
27
+ constructor(message: string, cause?: unknown);
28
+ }
29
+ export declare class CompilerError extends CrewhausError {
30
+ readonly name = "CompilerError";
31
+ constructor(message: string, cause?: unknown);
32
+ }
33
+ export declare class RuntimeError extends CrewhausError {
34
+ readonly name = "RuntimeError";
35
+ constructor(message: string, cause?: unknown);
36
+ }
37
+ export declare class ConfigError extends CrewhausError {
38
+ readonly name = "ConfigError";
39
+ constructor(message: string, cause?: unknown);
40
+ }
41
+ export declare class McpError extends CrewhausError {
42
+ readonly name: string;
43
+ constructor(message: string, cause?: unknown);
44
+ }
45
+ export declare class McpConnectionError extends McpError {
46
+ readonly name = "McpConnectionError";
47
+ constructor(message: string, cause?: unknown);
48
+ }
49
+ export declare class McpProtocolError extends McpError {
50
+ readonly name = "McpProtocolError";
51
+ constructor(message: string, cause?: unknown);
52
+ }
53
+ /**
54
+ * Section 17 — base for all model-provider adapter failures (auth, request
55
+ * marshalling, stream parsing, network). Carries `providerId` so callers can
56
+ * branch on which adapter raised; `cause` keeps the underlying SDK error
57
+ * accessible via `toJSON()` for the trace/log layer.
58
+ */
59
+ export declare class AdapterError extends CrewhausError {
60
+ readonly name: string;
61
+ readonly providerId: string;
62
+ constructor(providerId: string, message: string, cause?: unknown);
63
+ }
64
+ /**
65
+ * Section 17 — missing or invalid credentials for a model provider. Surfaces
66
+ * with a setup hint pointing at the relevant env var.
67
+ */
68
+ export declare class ProviderAuthError extends AdapterError {
69
+ readonly name = "ProviderAuthError";
70
+ constructor(providerId: string, message: string, cause?: unknown);
71
+ }
72
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,SAAS,GACjB,YAAY,GACZ,UAAU,GACV,SAAS,GACT,QAAQ,GACR,MAAM,GACN,KAAK,GACL,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,eAAe,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9D,CAAC;AAEF,qBAAa,aAAc,SAAQ,KAAK;IACtC,SAAkB,IAAI,EAAE,MAAM,CAAmB;IACjD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;gBAEb,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;IAK7D,MAAM,IAAI,eAAe;CAQ1B;AASD,qBAAa,cAAe,SAAQ,aAAa;IAC/C,SAAkB,IAAI,oBAAoB;gBAC9B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C;AAED,qBAAa,aAAc,SAAQ,aAAa;IAC9C,SAAkB,IAAI,mBAAmB;gBAC7B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C;AAED,qBAAa,YAAa,SAAQ,aAAa;IAC7C,SAAkB,IAAI,kBAAkB;gBAC5B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C;AAED,qBAAa,WAAY,SAAQ,aAAa;IAC5C,SAAkB,IAAI,iBAAiB;gBAC3B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C;AAED,qBAAa,QAAS,SAAQ,aAAa;IACzC,SAAkB,IAAI,EAAE,MAAM,CAAc;gBAChC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C;AAED,qBAAa,kBAAmB,SAAQ,QAAQ;IAC9C,SAAkB,IAAI,wBAAwB;gBAElC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C;AAED,qBAAa,gBAAiB,SAAQ,QAAQ;IAC5C,SAAkB,IAAI,sBAAsB;gBAEhC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C;AAED;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,aAAa;IAC7C,SAAkB,IAAI,EAAE,MAAM,CAAkB;IAChD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAChB,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAIjE;AAED;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,YAAY;IACjD,SAAkB,IAAI,uBAAuB;gBAEjC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAGjE"}
package/src/index.js ADDED
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Typed error hierarchy for factory.
3
+ * Catalog F-foundations (`error-types`) — every later layer imports this
4
+ * for structured error reporting instead of throwing raw `Error`s.
5
+ *
6
+ * Each error carries a stable `code` for programmatic dispatch and serializes
7
+ * its full cause chain via `toJSON()` for the logging layer.
8
+ */
9
+ export class CrewhausError extends Error {
10
+ name = "CrewhausError";
11
+ code;
12
+ constructor(code, message, cause) {
13
+ super(message, cause === undefined ? undefined : { cause });
14
+ this.code = code;
15
+ }
16
+ toJSON() {
17
+ return {
18
+ name: this.name,
19
+ code: this.code,
20
+ message: this.message,
21
+ cause: serializeCause(this.cause),
22
+ };
23
+ }
24
+ }
25
+ function serializeCause(cause) {
26
+ if (cause === undefined)
27
+ return undefined;
28
+ if (cause instanceof CrewhausError)
29
+ return cause.toJSON();
30
+ if (cause instanceof Error)
31
+ return { name: cause.name, message: cause.message };
32
+ return { message: String(cause) };
33
+ }
34
+ export class SpecParseError extends CrewhausError {
35
+ name = "SpecParseError";
36
+ constructor(message, cause) {
37
+ super("spec_parse", message, cause);
38
+ }
39
+ }
40
+ export class CompilerError extends CrewhausError {
41
+ name = "CompilerError";
42
+ constructor(message, cause) {
43
+ super("compiler", message, cause);
44
+ }
45
+ }
46
+ export class RuntimeError extends CrewhausError {
47
+ name = "RuntimeError";
48
+ constructor(message, cause) {
49
+ super("runtime", message, cause);
50
+ }
51
+ }
52
+ export class ConfigError extends CrewhausError {
53
+ name = "ConfigError";
54
+ constructor(message, cause) {
55
+ super("config", message, cause);
56
+ }
57
+ }
58
+ export class McpError extends CrewhausError {
59
+ name = "McpError";
60
+ constructor(message, cause) {
61
+ super("mcp", message, cause);
62
+ }
63
+ }
64
+ export class McpConnectionError extends McpError {
65
+ name = "McpConnectionError";
66
+ // 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)
67
+ constructor(message, cause) {
68
+ super(message, cause);
69
+ }
70
+ }
71
+ export class McpProtocolError extends McpError {
72
+ name = "McpProtocolError";
73
+ // 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)
74
+ constructor(message, cause) {
75
+ super(message, cause);
76
+ }
77
+ }
78
+ /**
79
+ * Section 17 — base for all model-provider adapter failures (auth, request
80
+ * marshalling, stream parsing, network). Carries `providerId` so callers can
81
+ * branch on which adapter raised; `cause` keeps the underlying SDK error
82
+ * accessible via `toJSON()` for the trace/log layer.
83
+ */
84
+ export class AdapterError extends CrewhausError {
85
+ name = "AdapterError";
86
+ providerId;
87
+ constructor(providerId, message, cause) {
88
+ super("adapter", message, cause);
89
+ this.providerId = providerId;
90
+ }
91
+ }
92
+ /**
93
+ * Section 17 — missing or invalid credentials for a model provider. Surfaces
94
+ * with a setup hint pointing at the relevant env var.
95
+ */
96
+ export class ProviderAuthError extends AdapterError {
97
+ name = "ProviderAuthError";
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(providerId, message, cause) {
100
+ super(providerId, message, cause);
101
+ }
102
+ }
103
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
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
  }