@cyanheads/mcp-ts-core 0.13.11 → 0.13.13
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/AGENTS.md +9 -8
- package/CLAUDE.md +9 -8
- package/README.md +1 -1
- package/changelog/0.13.x/0.13.12.md +50 -0
- package/changelog/0.13.x/0.13.13.md +93 -0
- package/dist/core/context.d.ts +12 -0
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +59 -14
- package/dist/core/context.js.map +1 -1
- package/dist/core/worker.d.ts.map +1 -1
- package/dist/core/worker.js +21 -8
- package/dist/core/worker.js.map +1 -1
- package/dist/mcp-server/handlerContext.d.ts +14 -8
- package/dist/mcp-server/handlerContext.d.ts.map +1 -1
- package/dist/mcp-server/handlerContext.js +16 -9
- package/dist/mcp-server/handlerContext.js.map +1 -1
- package/dist/mcp-server/inputRequired.d.ts +18 -9
- package/dist/mcp-server/inputRequired.d.ts.map +1 -1
- package/dist/mcp-server/inputRequired.js +29 -15
- package/dist/mcp-server/inputRequired.js.map +1 -1
- package/dist/mcp-server/prompts/prompt-registration.d.ts.map +1 -1
- package/dist/mcp-server/prompts/prompt-registration.js +10 -7
- package/dist/mcp-server/prompts/prompt-registration.js.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js +29 -19
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js.map +1 -1
- package/dist/mcp-server/tools/utils/inputPrevalidation.d.ts +8 -2
- package/dist/mcp-server/tools/utils/inputPrevalidation.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/inputPrevalidation.js +18 -7
- package/dist/mcp-server/tools/utils/inputPrevalidation.js.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts +7 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js +107 -21
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -1
- package/dist/mcp-server/transports/auth/lib/authUtils.d.ts +22 -0
- package/dist/mcp-server/transports/auth/lib/authUtils.d.ts.map +1 -1
- package/dist/mcp-server/transports/auth/lib/authUtils.js +29 -1
- package/dist/mcp-server/transports/auth/lib/authUtils.js.map +1 -1
- package/dist/mcp-server/transports/auth/lib/checkScopes.d.ts.map +1 -1
- package/dist/mcp-server/transports/auth/lib/checkScopes.js +2 -1
- package/dist/mcp-server/transports/auth/lib/checkScopes.js.map +1 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.js +4 -2
- package/dist/mcp-server/transports/http/httpErrorHandler.js.map +1 -1
- package/dist/services/mirror/sqlite/handle.d.ts +13 -2
- package/dist/services/mirror/sqlite/handle.d.ts.map +1 -1
- package/dist/services/mirror/sqlite/handle.js +17 -6
- package/dist/services/mirror/sqlite/handle.js.map +1 -1
- package/dist/services/mirror/sqlite/sqliteMirrorStore.d.ts.map +1 -1
- package/dist/services/mirror/sqlite/sqliteMirrorStore.js +3 -2
- package/dist/services/mirror/sqlite/sqliteMirrorStore.js.map +1 -1
- package/dist/storage/providers/fileSystem/fileSystemProvider.d.ts.map +1 -1
- package/dist/storage/providers/fileSystem/fileSystemProvider.js +48 -21
- package/dist/storage/providers/fileSystem/fileSystemProvider.js.map +1 -1
- package/dist/types-global/errors.d.ts.map +1 -1
- package/dist/types-global/errors.js +31 -16
- package/dist/types-global/errors.js.map +1 -1
- package/dist/utils/internal/error-handler/errorHandler.d.ts +29 -11
- package/dist/utils/internal/error-handler/errorHandler.d.ts.map +1 -1
- package/dist/utils/internal/error-handler/errorHandler.js +204 -95
- package/dist/utils/internal/error-handler/errorHandler.js.map +1 -1
- package/dist/utils/internal/error-handler/helpers.d.ts +91 -9
- package/dist/utils/internal/error-handler/helpers.d.ts.map +1 -1
- package/dist/utils/internal/error-handler/helpers.js +243 -39
- package/dist/utils/internal/error-handler/helpers.js.map +1 -1
- package/dist/utils/internal/error-handler/types.d.ts +21 -4
- package/dist/utils/internal/error-handler/types.d.ts.map +1 -1
- package/dist/utils/internal/logValue.d.ts +33 -0
- package/dist/utils/internal/logValue.d.ts.map +1 -0
- package/dist/utils/internal/logValue.js +539 -0
- package/dist/utils/internal/logValue.js.map +1 -0
- package/dist/utils/internal/logger.d.ts +38 -9
- package/dist/utils/internal/logger.d.ts.map +1 -1
- package/dist/utils/internal/logger.js +228 -118
- package/dist/utils/internal/logger.js.map +1 -1
- package/dist/utils/internal/observabilityCap.d.ts +35 -0
- package/dist/utils/internal/observabilityCap.d.ts.map +1 -0
- package/dist/utils/internal/observabilityCap.js +43 -0
- package/dist/utils/internal/observabilityCap.js.map +1 -0
- package/dist/utils/internal/performance.d.ts.map +1 -1
- package/dist/utils/internal/performance.js +9 -11
- package/dist/utils/internal/performance.js.map +1 -1
- package/dist/utils/internal/requestContext.d.ts +3 -3
- package/dist/utils/internal/requestContext.js +1 -1
- package/dist/utils/network/fetchWithTimeout.d.ts +20 -10
- package/dist/utils/network/fetchWithTimeout.d.ts.map +1 -1
- package/dist/utils/network/fetchWithTimeout.js +112 -30
- package/dist/utils/network/fetchWithTimeout.js.map +1 -1
- package/dist/utils/network/httpError.d.ts +8 -6
- package/dist/utils/network/httpError.d.ts.map +1 -1
- package/dist/utils/network/httpError.js +23 -7
- package/dist/utils/network/httpError.js.map +1 -1
- package/dist/utils/network/retry.d.ts +25 -2
- package/dist/utils/network/retry.d.ts.map +1 -1
- package/dist/utils/network/retry.js +47 -5
- package/dist/utils/network/retry.js.map +1 -1
- package/dist/utils/security/sanitization.d.ts +24 -28
- package/dist/utils/security/sanitization.d.ts.map +1 -1
- package/dist/utils/security/sanitization.js +25 -84
- package/dist/utils/security/sanitization.js.map +1 -1
- package/dist/utils/security/sensitiveFields.d.ts +32 -4
- package/dist/utils/security/sensitiveFields.d.ts.map +1 -1
- package/dist/utils/security/sensitiveFields.js +85 -4
- package/dist/utils/security/sensitiveFields.js.map +1 -1
- package/dist/utils/telemetry/trace.d.ts +3 -1
- package/dist/utils/telemetry/trace.d.ts.map +1 -1
- package/dist/utils/telemetry/trace.js +6 -6
- package/dist/utils/telemetry/trace.js.map +1 -1
- package/framework-skills/api-auth/SKILL.md +3 -1
- package/framework-skills/api-canvas/SKILL.md +2 -2
- package/framework-skills/api-config/SKILL.md +2 -1
- package/framework-skills/api-context/SKILL.md +6 -6
- package/framework-skills/api-errors/SKILL.md +19 -17
- package/framework-skills/api-linter/SKILL.md +11 -10
- package/framework-skills/api-mirror/SKILL.md +3 -1
- package/framework-skills/api-telemetry/SKILL.md +14 -8
- package/framework-skills/api-utils/SKILL.md +6 -6
- package/framework-skills/api-utils/references/security.md +4 -2
- package/framework-skills/field-test/SKILL.md +2 -2
- package/framework-skills/git-wrapup/SKILL.md +3 -3
- package/framework-skills/tool-defs-analysis/SKILL.md +2 -2
- package/package.json +10 -9
- package/scripts/check-framework-antipatterns.ts +3 -2
- package/templates/.env.example +2 -0
- package/templates/tests/tools/echo.tool.test.ts +19 -1
|
@@ -3,31 +3,97 @@
|
|
|
3
3
|
* Enhanced with cause chain extraction and circular reference detection.
|
|
4
4
|
* @module src/utils/internal/error-handler/helpers
|
|
5
5
|
*/
|
|
6
|
+
import { type Span } from '@opentelemetry/api';
|
|
6
7
|
import { ZodError } from 'zod';
|
|
7
8
|
/**
|
|
8
|
-
*
|
|
9
|
+
* What the error path writes for a field whose read throws — a getter, a
|
|
10
|
+
* `Proxy` trap, a revoked `Proxy` — as the log-data walk does.
|
|
11
|
+
*/
|
|
12
|
+
export declare const UNREADABLE = "[Unreadable]";
|
|
13
|
+
/** `value[key]`, or {@link UNREADABLE} when reading it throws. */
|
|
14
|
+
export declare function readField(value: object, key: PropertyKey): unknown;
|
|
15
|
+
/**
|
|
16
|
+
* An error's `message` or `name`, as read, written as text: a string as it is;
|
|
17
|
+
* any other primitive as `String` converts it, which runs no caller code and
|
|
18
|
+
* never throws, a `Symbol` included (`'Symbol(description)'`), so a `message`
|
|
19
|
+
* set to `404` reads `'404'`; and an object or function as {@link UNREADABLE},
|
|
20
|
+
* since converting one runs its own `toString`, which can throw or return
|
|
21
|
+
* anything.
|
|
22
|
+
*/
|
|
23
|
+
export declare function errorText(value: unknown): string;
|
|
24
|
+
/**
|
|
25
|
+
* `value instanceof type`, or `false` when the check throws — a revoked
|
|
26
|
+
* `Proxy`, a `getPrototypeOf` trap — so such a value is handled as the
|
|
27
|
+
* non-instance it cannot be shown not to be.
|
|
28
|
+
*/
|
|
29
|
+
export declare function isInstance<T>(value: unknown, type: abstract new (...args: never[]) => T): value is T;
|
|
30
|
+
/**
|
|
31
|
+
* A copy of `value`'s own enumerable fields, as a spread makes it (`{}` for
|
|
32
|
+
* `undefined`), or `undefined` when making it throws — a getter that throws, a
|
|
33
|
+
* `Proxy` whose trap throws.
|
|
34
|
+
*/
|
|
35
|
+
export declare function copyFields<T extends object>(value: T | undefined): T | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* A shallow copy of the `data` a thrown `McpError` carries, so the error path
|
|
38
|
+
* reads plain fields rather than the thrown value's. Nothing is serialized: the
|
|
39
|
+
* log record writes the copy through the bounded log walk, and the wire
|
|
40
|
+
* boundaries check it with {@link readWireErrorData}. `undefined` when `error`
|
|
41
|
+
* is not an `McpError`, carries no object `data`, or its `data` cannot be read
|
|
42
|
+
* or copied — a getter, a revoked `Proxy`, a throwing `ownKeys` trap.
|
|
43
|
+
*/
|
|
44
|
+
export declare function readErrorData(error: unknown): Record<string, unknown> | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* {@link readErrorData} for a response: every field is one the wire carries.
|
|
47
|
+
* A field `JSON.stringify` cannot write is {@link UNREADABLE}, since a response
|
|
48
|
+
* holding one is never sent and the client waits for it, and a field that takes
|
|
49
|
+
* more than {@link WIRE_VALUES} JSON values to write is `'[Truncated]'`. Every
|
|
50
|
+
* other field is the thrown value itself, so readable `data` is sent byte for
|
|
51
|
+
* byte as thrown.
|
|
52
|
+
*/
|
|
53
|
+
export declare function readWireErrorData(error: unknown): Record<string, unknown> | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* `value` when it is an `Error`, else an `Error` whose message is `String(value)`
|
|
56
|
+
* — or {@link UNREADABLE} when the value can be neither checked nor converted
|
|
57
|
+
* (a revoked `Proxy`, a null-prototype object).
|
|
58
|
+
*/
|
|
59
|
+
export declare function asError(value: unknown): Error;
|
|
60
|
+
/**
|
|
61
|
+
* Marks `span` failed with `error`: records an `Error` as the span's exception,
|
|
62
|
+
* then sets the `ERROR` status with its `message` (any other value as `String`
|
|
63
|
+
* converts it). Never throws: an exception the span cannot read — a field
|
|
64
|
+
* whose getter throws, which the SDK's `recordException` reads unguarded — is
|
|
65
|
+
* left unrecorded, and a message that cannot be read is {@link UNREADABLE}.
|
|
66
|
+
*/
|
|
67
|
+
export declare function recordSpanFailure(span: Span, error: unknown): void;
|
|
68
|
+
/**
|
|
69
|
+
* Formats a ZodError as a single readable line: `<dotted.path>: <message>`.
|
|
9
70
|
*
|
|
10
71
|
* `ZodError.message` is a serialized JSON array of `ZodIssue` objects — useful for
|
|
11
72
|
* debugging but unreadable in logs, client error messages, and UI surfaces. This
|
|
12
|
-
* helper
|
|
13
|
-
*
|
|
73
|
+
* helper renders the first issue (typically the most actionable) with its path
|
|
74
|
+
* leading, the form every other path-bearing renderer in the framework uses, so
|
|
75
|
+
* a custom message written as a full sentence stays intact. An issue with an
|
|
76
|
+
* empty path renders as its bare message, and a count of the remaining issues
|
|
77
|
+
* trails as ` (+N more)`.
|
|
14
78
|
*
|
|
15
79
|
* Pair with `ErrorHandler.classifyOnly` (which returns `data: { issues }`) to
|
|
16
80
|
* preserve the structured issue array for clients that can render field-level
|
|
17
81
|
* errors.
|
|
18
82
|
*
|
|
19
83
|
* @param err - The ZodError to format.
|
|
20
|
-
* @returns A single
|
|
84
|
+
* @returns A single line, e.g. `"nctId: Invalid input: expected string, received number (+2 more)"`.
|
|
21
85
|
*/
|
|
22
86
|
export declare function formatZodErrorMessage(err: ZodError): string;
|
|
23
87
|
/**
|
|
24
88
|
* Retrieves a descriptive name for an error object or value.
|
|
25
89
|
*
|
|
26
|
-
* - `Error` instances → `error.name` (e.g. `'TypeError'`), falling back to `'Error'
|
|
90
|
+
* - `Error` instances → `error.name` (e.g. `'TypeError'`), falling back to `'Error'`;
|
|
91
|
+
* a `name` that is not a string is written as {@link errorText} writes it.
|
|
27
92
|
* - `null` → `'NullValueEncountered'`
|
|
28
93
|
* - `undefined` → `'UndefinedValueEncountered'`
|
|
29
94
|
* - Non-plain objects with a named constructor → `'<ConstructorName>Encountered'`
|
|
30
95
|
* - Everything else → `'<typeof value>Encountered'` (e.g. `'stringEncountered'`)
|
|
96
|
+
* - A value whose inspection throws (a `name` getter, a revoked `Proxy`) → `'[Unreadable]'`
|
|
31
97
|
*
|
|
32
98
|
* @param error - The error object or value.
|
|
33
99
|
* @returns A stable, human-readable string identifying the error's type.
|
|
@@ -44,13 +110,16 @@ export declare function getErrorName(error: unknown): string;
|
|
|
44
110
|
* Extracts a human-readable message string from any thrown value.
|
|
45
111
|
*
|
|
46
112
|
* Handles every JavaScript type so that `catch (e)` blocks never produce `[object Object]`:
|
|
47
|
-
* - `AggregateError` → combines up to 3 inner error messages after the outer message
|
|
48
|
-
*
|
|
113
|
+
* - `AggregateError` → combines up to 3 inner error messages after the outer message,
|
|
114
|
+
* each one that cannot be read as `'[Unreadable]'`.
|
|
115
|
+
* - `Error` → `error.message`, or `'[Unreadable]'` when reading it throws (a getter);
|
|
116
|
+
* a `message` that is not a string, the outer's or a member's, as {@link errorText} writes it.
|
|
49
117
|
* - `null` / `undefined` → descriptive literal strings.
|
|
50
118
|
* - Primitives (`string`, `number`, `boolean`, `bigint`, `symbol`) → string-coerced value.
|
|
51
119
|
* - Functions → `[function <name>]`
|
|
52
120
|
* - Objects → JSON-serialized if possible; otherwise constructor name fallback.
|
|
53
|
-
* -
|
|
121
|
+
* - A value whose inspection throws (a getter, a `Proxy` trap, a revoked `Proxy`) →
|
|
122
|
+
* `'[Unreadable]'`, never the text of what the read threw.
|
|
54
123
|
*
|
|
55
124
|
* @param error - The thrown value to extract a message from.
|
|
56
125
|
* @returns A non-empty string describing the error.
|
|
@@ -72,6 +141,13 @@ export declare function getErrorMessage(error: unknown): string;
|
|
|
72
141
|
* with `depth: 0` being the original (outermost) error and increasing depth tracking nested causes.
|
|
73
142
|
*/
|
|
74
143
|
export interface ErrorCauseNode {
|
|
144
|
+
/**
|
|
145
|
+
* The error's own string `code`, when it carries one — the transport code a
|
|
146
|
+
* fetch failure keeps: `ECONNREFUSED` on the `cause` of Node's
|
|
147
|
+
* `TypeError: fetch failed`, `ConnectionRefused` on Bun's rejection itself.
|
|
148
|
+
* `McpError`'s numeric JSON-RPC code is not copied.
|
|
149
|
+
*/
|
|
150
|
+
code?: string;
|
|
75
151
|
/** Additional data from McpError instances */
|
|
76
152
|
data?: Record<string, unknown>;
|
|
77
153
|
/** Depth in the cause chain (0 = original error) */
|
|
@@ -92,8 +168,14 @@ export interface ErrorCauseNode {
|
|
|
92
168
|
* - or `maxDepth` is reached (sentinel node appended, then stops).
|
|
93
169
|
*
|
|
94
170
|
* String causes are treated as terminal `StringError` nodes.
|
|
95
|
-
* `McpError` nodes include the `data` property when present
|
|
171
|
+
* `McpError` nodes include the `data` property when present, and any `Error`
|
|
172
|
+
* node carrying a string `code` includes it.
|
|
96
173
|
* Circular references are detected via `WeakSet` identity tracking.
|
|
174
|
+
* Every read is guarded: a `name`, `message`, or `stack` whose read throws is
|
|
175
|
+
* `'[Unreadable]'` on its node, an unreadable `code` or `data` is left out, and
|
|
176
|
+
* a cause that cannot be read or inspected — a throwing `cause` getter, a
|
|
177
|
+
* revoked `Proxy` — ends the chain as a node whose `name` and `message` are
|
|
178
|
+
* both `'[Unreadable]'`.
|
|
97
179
|
*
|
|
98
180
|
* @param error - The outermost error to start traversal from.
|
|
99
181
|
* @param maxDepth - Maximum number of nodes to traverse before stopping. Defaults to `20`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/utils/internal/error-handler/helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAK/B
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/utils/internal/error-handler/helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,IAAI,EAAkB,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAK/B;;;GAGG;AACH,eAAO,MAAM,UAAU,iBAAiB,CAAC;AAEzC,kEAAkE;AAClE,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAMlE;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAKhD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAC1B,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,QAAQ,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,GACzC,KAAK,IAAI,CAAC,CAMZ;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,GAAG,CAAC,GAAG,SAAS,CAMhF;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAMjF;AAiCD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAKrF;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAM7C;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAiBlE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAQ3D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAwBnD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAsDtD;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAcD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAAK,GAAG,cAAc,EAAE,CA+EtF"}
|
|
@@ -3,42 +3,206 @@
|
|
|
3
3
|
* Enhanced with cause chain extraction and circular reference detection.
|
|
4
4
|
* @module src/utils/internal/error-handler/helpers
|
|
5
5
|
*/
|
|
6
|
+
import { SpanStatusCode } from '@opentelemetry/api';
|
|
6
7
|
import { ZodError } from 'zod';
|
|
7
8
|
import { McpError } from '../../../types-global/errors.js';
|
|
8
9
|
import { isAggregateError } from '../../types/guards.js';
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
+
* What the error path writes for a field whose read throws — a getter, a
|
|
12
|
+
* `Proxy` trap, a revoked `Proxy` — as the log-data walk does.
|
|
13
|
+
*/
|
|
14
|
+
export const UNREADABLE = '[Unreadable]';
|
|
15
|
+
/** `value[key]`, or {@link UNREADABLE} when reading it throws. */
|
|
16
|
+
export function readField(value, key) {
|
|
17
|
+
try {
|
|
18
|
+
return value[key];
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return UNREADABLE;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* An error's `message` or `name`, as read, written as text: a string as it is;
|
|
26
|
+
* any other primitive as `String` converts it, which runs no caller code and
|
|
27
|
+
* never throws, a `Symbol` included (`'Symbol(description)'`), so a `message`
|
|
28
|
+
* set to `404` reads `'404'`; and an object or function as {@link UNREADABLE},
|
|
29
|
+
* since converting one runs its own `toString`, which can throw or return
|
|
30
|
+
* anything.
|
|
31
|
+
*/
|
|
32
|
+
export function errorText(value) {
|
|
33
|
+
if (typeof value === 'string')
|
|
34
|
+
return value;
|
|
35
|
+
return value === null || (typeof value !== 'object' && typeof value !== 'function')
|
|
36
|
+
? String(value)
|
|
37
|
+
: UNREADABLE;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* `value instanceof type`, or `false` when the check throws — a revoked
|
|
41
|
+
* `Proxy`, a `getPrototypeOf` trap — so such a value is handled as the
|
|
42
|
+
* non-instance it cannot be shown not to be.
|
|
43
|
+
*/
|
|
44
|
+
export function isInstance(value, type) {
|
|
45
|
+
try {
|
|
46
|
+
return value instanceof type;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* A copy of `value`'s own enumerable fields, as a spread makes it (`{}` for
|
|
54
|
+
* `undefined`), or `undefined` when making it throws — a getter that throws, a
|
|
55
|
+
* `Proxy` whose trap throws.
|
|
56
|
+
*/
|
|
57
|
+
export function copyFields(value) {
|
|
58
|
+
try {
|
|
59
|
+
return { ...value };
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* A shallow copy of the `data` a thrown `McpError` carries, so the error path
|
|
67
|
+
* reads plain fields rather than the thrown value's. Nothing is serialized: the
|
|
68
|
+
* log record writes the copy through the bounded log walk, and the wire
|
|
69
|
+
* boundaries check it with {@link readWireErrorData}. `undefined` when `error`
|
|
70
|
+
* is not an `McpError`, carries no object `data`, or its `data` cannot be read
|
|
71
|
+
* or copied — a getter, a revoked `Proxy`, a throwing `ownKeys` trap.
|
|
72
|
+
*/
|
|
73
|
+
export function readErrorData(error) {
|
|
74
|
+
if (!isInstance(error, McpError))
|
|
75
|
+
return;
|
|
76
|
+
const data = readField(error, 'data');
|
|
77
|
+
return typeof data === 'object' && data !== null
|
|
78
|
+
? copyFields(data)
|
|
79
|
+
: undefined;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* JSON values one `data` field may take to write before the wire check gives it
|
|
83
|
+
* up: about 6 MB of JSON, checked in tens of milliseconds. `JSON.stringify`
|
|
84
|
+
* writes a shared object once per reference, so 17 objects that each refer to
|
|
85
|
+
* the next three times write 43 million values: seconds and gigabytes to
|
|
86
|
+
* serialize, and a response a stdio client cannot read.
|
|
87
|
+
*/
|
|
88
|
+
const WIRE_VALUES = 1_000_000;
|
|
89
|
+
/** Thrown by the wire check's replacer once a field passes {@link WIRE_VALUES}. */
|
|
90
|
+
const OVER_WIRE_BUDGET = Symbol('over wire budget');
|
|
91
|
+
/**
|
|
92
|
+
* `value` when `JSON.stringify` writes it within {@link WIRE_VALUES} values;
|
|
93
|
+
* `'[Truncated]'` when it would take more, and {@link UNREADABLE} when it
|
|
94
|
+
* cannot be written at all — a getter or a revoked `Proxy` that throws on read
|
|
95
|
+
* at any depth, a `BigInt`, a cycle, a `toJSON` that throws.
|
|
96
|
+
*/
|
|
97
|
+
function wireField(value) {
|
|
98
|
+
let values = 0;
|
|
99
|
+
try {
|
|
100
|
+
JSON.stringify(value, (_key, field) => {
|
|
101
|
+
if (++values > WIRE_VALUES)
|
|
102
|
+
throw OVER_WIRE_BUDGET;
|
|
103
|
+
return field;
|
|
104
|
+
});
|
|
105
|
+
return value;
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
return error === OVER_WIRE_BUDGET ? '[Truncated]' : UNREADABLE;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* {@link readErrorData} for a response: every field is one the wire carries.
|
|
113
|
+
* A field `JSON.stringify` cannot write is {@link UNREADABLE}, since a response
|
|
114
|
+
* holding one is never sent and the client waits for it, and a field that takes
|
|
115
|
+
* more than {@link WIRE_VALUES} JSON values to write is `'[Truncated]'`. Every
|
|
116
|
+
* other field is the thrown value itself, so readable `data` is sent byte for
|
|
117
|
+
* byte as thrown.
|
|
118
|
+
*/
|
|
119
|
+
export function readWireErrorData(error) {
|
|
120
|
+
const copy = readErrorData(error);
|
|
121
|
+
if (copy === undefined)
|
|
122
|
+
return;
|
|
123
|
+
for (const key of Object.keys(copy))
|
|
124
|
+
copy[key] = wireField(copy[key]);
|
|
125
|
+
return copy;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* `value` when it is an `Error`, else an `Error` whose message is `String(value)`
|
|
129
|
+
* — or {@link UNREADABLE} when the value can be neither checked nor converted
|
|
130
|
+
* (a revoked `Proxy`, a null-prototype object).
|
|
131
|
+
*/
|
|
132
|
+
export function asError(value) {
|
|
133
|
+
try {
|
|
134
|
+
return value instanceof Error ? value : new Error(String(value));
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return new Error(UNREADABLE);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Marks `span` failed with `error`: records an `Error` as the span's exception,
|
|
142
|
+
* then sets the `ERROR` status with its `message` (any other value as `String`
|
|
143
|
+
* converts it). Never throws: an exception the span cannot read — a field
|
|
144
|
+
* whose getter throws, which the SDK's `recordException` reads unguarded — is
|
|
145
|
+
* left unrecorded, and a message that cannot be read is {@link UNREADABLE}.
|
|
146
|
+
*/
|
|
147
|
+
export function recordSpanFailure(span, error) {
|
|
148
|
+
let message;
|
|
149
|
+
try {
|
|
150
|
+
if (error instanceof Error) {
|
|
151
|
+
try {
|
|
152
|
+
span.recordException(error);
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// The span could not read it; the status below still marks the failure.
|
|
156
|
+
}
|
|
157
|
+
message = String(error.message);
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
message = String(error);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
message = UNREADABLE;
|
|
165
|
+
}
|
|
166
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message });
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Formats a ZodError as a single readable line: `<dotted.path>: <message>`.
|
|
11
170
|
*
|
|
12
171
|
* `ZodError.message` is a serialized JSON array of `ZodIssue` objects — useful for
|
|
13
172
|
* debugging but unreadable in logs, client error messages, and UI surfaces. This
|
|
14
|
-
* helper
|
|
15
|
-
*
|
|
173
|
+
* helper renders the first issue (typically the most actionable) with its path
|
|
174
|
+
* leading, the form every other path-bearing renderer in the framework uses, so
|
|
175
|
+
* a custom message written as a full sentence stays intact. An issue with an
|
|
176
|
+
* empty path renders as its bare message, and a count of the remaining issues
|
|
177
|
+
* trails as ` (+N more)`.
|
|
16
178
|
*
|
|
17
179
|
* Pair with `ErrorHandler.classifyOnly` (which returns `data: { issues }`) to
|
|
18
180
|
* preserve the structured issue array for clients that can render field-level
|
|
19
181
|
* errors.
|
|
20
182
|
*
|
|
21
183
|
* @param err - The ZodError to format.
|
|
22
|
-
* @returns A single
|
|
184
|
+
* @returns A single line, e.g. `"nctId: Invalid input: expected string, received number (+2 more)"`.
|
|
23
185
|
*/
|
|
24
186
|
export function formatZodErrorMessage(err) {
|
|
25
187
|
const issues = err.issues;
|
|
26
188
|
const first = issues[0];
|
|
27
189
|
if (!first)
|
|
28
190
|
return 'Validation failed';
|
|
29
|
-
const path = first.path.length > 0 ?
|
|
191
|
+
const path = first.path.length > 0 ? `${first.path.map(String).join('.')}: ` : '';
|
|
30
192
|
const rest = issues.length - 1;
|
|
31
193
|
const tail = rest > 0 ? ` (+${rest} more)` : '';
|
|
32
|
-
return `${first.message}${
|
|
194
|
+
return `${path}${first.message}${tail}`;
|
|
33
195
|
}
|
|
34
196
|
/**
|
|
35
197
|
* Retrieves a descriptive name for an error object or value.
|
|
36
198
|
*
|
|
37
|
-
* - `Error` instances → `error.name` (e.g. `'TypeError'`), falling back to `'Error'
|
|
199
|
+
* - `Error` instances → `error.name` (e.g. `'TypeError'`), falling back to `'Error'`;
|
|
200
|
+
* a `name` that is not a string is written as {@link errorText} writes it.
|
|
38
201
|
* - `null` → `'NullValueEncountered'`
|
|
39
202
|
* - `undefined` → `'UndefinedValueEncountered'`
|
|
40
203
|
* - Non-plain objects with a named constructor → `'<ConstructorName>Encountered'`
|
|
41
204
|
* - Everything else → `'<typeof value>Encountered'` (e.g. `'stringEncountered'`)
|
|
205
|
+
* - A value whose inspection throws (a `name` getter, a revoked `Proxy`) → `'[Unreadable]'`
|
|
42
206
|
*
|
|
43
207
|
* @param error - The error object or value.
|
|
44
208
|
* @returns A stable, human-readable string identifying the error's type.
|
|
@@ -51,35 +215,43 @@ export function formatZodErrorMessage(err) {
|
|
|
51
215
|
* ```
|
|
52
216
|
*/
|
|
53
217
|
export function getErrorName(error) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
218
|
+
try {
|
|
219
|
+
if (error instanceof Error) {
|
|
220
|
+
const name = readField(error, 'name');
|
|
221
|
+
return name ? errorText(name) : 'Error';
|
|
222
|
+
}
|
|
223
|
+
if (error === null) {
|
|
224
|
+
return 'NullValueEncountered';
|
|
225
|
+
}
|
|
226
|
+
if (error === undefined) {
|
|
227
|
+
return 'UndefinedValueEncountered';
|
|
228
|
+
}
|
|
229
|
+
if (typeof error === 'object' &&
|
|
230
|
+
error.constructor &&
|
|
231
|
+
typeof error.constructor.name === 'string' &&
|
|
232
|
+
error.constructor.name !== 'Object') {
|
|
233
|
+
return `${error.constructor.name}Encountered`;
|
|
234
|
+
}
|
|
235
|
+
return `${typeof error}Encountered`;
|
|
62
236
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
error.constructor &&
|
|
66
|
-
typeof error.constructor.name === 'string' &&
|
|
67
|
-
error.constructor.name !== 'Object') {
|
|
68
|
-
return `${error.constructor.name}Encountered`;
|
|
237
|
+
catch {
|
|
238
|
+
return UNREADABLE;
|
|
69
239
|
}
|
|
70
|
-
return `${typeof error}Encountered`;
|
|
71
240
|
}
|
|
72
241
|
/**
|
|
73
242
|
* Extracts a human-readable message string from any thrown value.
|
|
74
243
|
*
|
|
75
244
|
* Handles every JavaScript type so that `catch (e)` blocks never produce `[object Object]`:
|
|
76
|
-
* - `AggregateError` → combines up to 3 inner error messages after the outer message
|
|
77
|
-
*
|
|
245
|
+
* - `AggregateError` → combines up to 3 inner error messages after the outer message,
|
|
246
|
+
* each one that cannot be read as `'[Unreadable]'`.
|
|
247
|
+
* - `Error` → `error.message`, or `'[Unreadable]'` when reading it throws (a getter);
|
|
248
|
+
* a `message` that is not a string, the outer's or a member's, as {@link errorText} writes it.
|
|
78
249
|
* - `null` / `undefined` → descriptive literal strings.
|
|
79
250
|
* - Primitives (`string`, `number`, `boolean`, `bigint`, `symbol`) → string-coerced value.
|
|
80
251
|
* - Functions → `[function <name>]`
|
|
81
252
|
* - Objects → JSON-serialized if possible; otherwise constructor name fallback.
|
|
82
|
-
* -
|
|
253
|
+
* - A value whose inspection throws (a getter, a `Proxy` trap, a revoked `Proxy`) →
|
|
254
|
+
* `'[Unreadable]'`, never the text of what the read threw.
|
|
83
255
|
*
|
|
84
256
|
* @param error - The thrown value to extract a message from.
|
|
85
257
|
* @returns A non-empty string describing the error.
|
|
@@ -100,16 +272,17 @@ export function getErrorMessage(error) {
|
|
|
100
272
|
return formatZodErrorMessage(error);
|
|
101
273
|
}
|
|
102
274
|
if (error instanceof Error) {
|
|
275
|
+
const message = errorText(readField(error, 'message'));
|
|
103
276
|
// AggregateError should surface combined messages succinctly
|
|
104
277
|
if (isAggregateError(error)) {
|
|
105
278
|
const inner = error.errors
|
|
106
|
-
.map((e) => (e
|
|
279
|
+
.map((e) => errorText(readField(asError(e), 'message')))
|
|
107
280
|
.filter(Boolean)
|
|
108
281
|
.slice(0, 3)
|
|
109
282
|
.join('; ');
|
|
110
|
-
return inner ? `${
|
|
283
|
+
return inner ? `${message}: ${inner}` : message;
|
|
111
284
|
}
|
|
112
|
-
return
|
|
285
|
+
return message;
|
|
113
286
|
}
|
|
114
287
|
if (error === null) {
|
|
115
288
|
return 'Null value encountered as error';
|
|
@@ -147,8 +320,19 @@ export function getErrorMessage(error) {
|
|
|
147
320
|
// c8 ignore next
|
|
148
321
|
return '[unrepresentable error]';
|
|
149
322
|
}
|
|
150
|
-
catch
|
|
151
|
-
return
|
|
323
|
+
catch {
|
|
324
|
+
return UNREADABLE;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/** Stands in, inside {@link extractErrorCauseChain}, for a `cause` whose read threw. */
|
|
328
|
+
const UNREADABLE_CAUSE = Symbol('unreadable cause');
|
|
329
|
+
/** `value instanceof Error`, or `undefined` when the check throws: a revoked `Proxy`, a `getPrototypeOf` trap. */
|
|
330
|
+
function errorCheck(value) {
|
|
331
|
+
try {
|
|
332
|
+
return value instanceof Error;
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
return;
|
|
152
336
|
}
|
|
153
337
|
}
|
|
154
338
|
/**
|
|
@@ -160,8 +344,14 @@ export function getErrorMessage(error) {
|
|
|
160
344
|
* - or `maxDepth` is reached (sentinel node appended, then stops).
|
|
161
345
|
*
|
|
162
346
|
* String causes are treated as terminal `StringError` nodes.
|
|
163
|
-
* `McpError` nodes include the `data` property when present
|
|
347
|
+
* `McpError` nodes include the `data` property when present, and any `Error`
|
|
348
|
+
* node carrying a string `code` includes it.
|
|
164
349
|
* Circular references are detected via `WeakSet` identity tracking.
|
|
350
|
+
* Every read is guarded: a `name`, `message`, or `stack` whose read throws is
|
|
351
|
+
* `'[Unreadable]'` on its node, an unreadable `code` or `data` is left out, and
|
|
352
|
+
* a cause that cannot be read or inspected — a throwing `cause` getter, a
|
|
353
|
+
* revoked `Proxy` — ends the chain as a node whose `name` and `message` are
|
|
354
|
+
* both `'[Unreadable]'`.
|
|
165
355
|
*
|
|
166
356
|
* @param error - The outermost error to start traversal from.
|
|
167
357
|
* @param maxDepth - Maximum number of nodes to traverse before stopping. Defaults to `20`.
|
|
@@ -197,21 +387,35 @@ export function extractErrorCauseChain(error, maxDepth = 20) {
|
|
|
197
387
|
}
|
|
198
388
|
seen.add(current);
|
|
199
389
|
}
|
|
200
|
-
|
|
390
|
+
const isError = current === UNREADABLE_CAUSE ? undefined : errorCheck(current);
|
|
391
|
+
if (isError === undefined) {
|
|
392
|
+
chain.push({ name: UNREADABLE, message: UNREADABLE, depth });
|
|
393
|
+
break;
|
|
394
|
+
}
|
|
395
|
+
if (isError) {
|
|
396
|
+
const err = current;
|
|
397
|
+
const code = readField(err, 'code');
|
|
398
|
+
const stack = readField(err, 'stack');
|
|
201
399
|
const node = {
|
|
202
|
-
name:
|
|
203
|
-
message:
|
|
400
|
+
name: errorText(readField(err, 'name')),
|
|
401
|
+
message: errorText(readField(err, 'message')),
|
|
204
402
|
depth,
|
|
403
|
+
...(typeof code === 'string' && code !== UNREADABLE ? { code } : {}),
|
|
205
404
|
// Only include stack if it exists (exact optional property types)
|
|
206
|
-
...(
|
|
405
|
+
...(stack !== undefined ? { stack: stack } : {}),
|
|
207
406
|
};
|
|
208
407
|
// Extract data from McpError instances
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
408
|
+
const data = err instanceof McpError ? readField(err, 'data') : undefined;
|
|
409
|
+
if (data && data !== UNREADABLE)
|
|
410
|
+
node.data = data;
|
|
212
411
|
chain.push(node);
|
|
213
412
|
// Continue traversing cause chain
|
|
214
|
-
|
|
413
|
+
try {
|
|
414
|
+
current = err.cause;
|
|
415
|
+
}
|
|
416
|
+
catch {
|
|
417
|
+
current = UNREADABLE_CAUSE;
|
|
418
|
+
}
|
|
215
419
|
}
|
|
216
420
|
else if (typeof current === 'string') {
|
|
217
421
|
chain.push({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../../src/utils/internal/error-handler/helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAE/B,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../../src/utils/internal/error-handler/helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAa,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAE/B,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,cAAc,CAAC;AAEzC,kEAAkE;AAClE,MAAM,UAAU,SAAS,CAAC,KAAa,EAAE,GAAgB;IACvD,IAAI,CAAC;QACH,OAAQ,KAAsC,CAAC,GAAG,CAAC,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,UAAU,CAAC;IACpB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,OAAO,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,UAAU,CAAC;QACjF,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QACf,CAAC,CAAC,UAAU,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,KAAc,EACd,IAA0C;IAE1C,IAAI,CAAC;QACH,OAAO,KAAK,YAAY,IAAI,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAmB,KAAoB;IAC/D,IAAI,CAAC;QACH,OAAO,EAAE,GAAG,KAAK,EAAO,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC;QAAE,OAAO;IACzC,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACtC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;QAC9C,CAAC,CAAC,UAAU,CAAC,IAA+B,CAAC;QAC7C,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,GAAG,SAAS,CAAC;AAE9B,mFAAmF;AACnF,MAAM,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAEpD;;;;;GAKG;AACH,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,CAAC;QACH,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,KAAc,EAAE,EAAE;YAC7C,IAAI,EAAE,MAAM,GAAG,WAAW;gBAAE,MAAM,gBAAgB,CAAC;YACnD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,KAAK,KAAK,gBAAgB,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC;IACjE,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO;IAC/B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,IAAI,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACtE,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,IAAI,CAAC;QACH,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAU,EAAE,KAAc;IAC1D,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACP,wEAAwE;YAC1E,CAAC;YACD,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,UAAU,CAAC;IACvB,CAAC;IACD,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAa;IACjD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACxB,IAAI,CAAC,KAAK;QAAE,OAAO,mBAAmB,CAAC;IACvC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAClF,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAChD,OAAO,GAAG,IAAI,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,CAAC;QACH,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACtC,OAAO,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QAC1C,CAAC;QACD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,sBAAsB,CAAC;QAChC,CAAC;QACD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,2BAA2B,CAAC;QACrC,CAAC;QACD,IACE,OAAO,KAAK,KAAK,QAAQ;YACzB,KAAK,CAAC,WAAW;YACjB,OAAO,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,QAAQ;YAC1C,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,QAAQ,EACnC,CAAC;YACD,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,aAAa,CAAC;QAChD,CAAC;QACD,OAAO,GAAG,OAAO,KAAK,aAAa,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,UAAU,CAAC;IACpB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,CAAC;QACH,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;YAC9B,OAAO,qBAAqB,CAAC,KAAK,CAAC,CAAC;QACtC,CAAC;QACD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;YACvD,6DAA6D;YAC7D,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM;qBACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;qBACvD,MAAM,CAAC,OAAO,CAAC;qBACf,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;qBACX,IAAI,CAAC,IAAI,CAAC,CAAC;gBACd,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YAClD,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,iCAAiC,CAAC;QAC3C,CAAC;QACD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,sCAAsC,CAAC;QAChD,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YAC5D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC1B,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;YAChC,OAAO,aAAa,KAAK,CAAC,IAAI,IAAI,WAAW,GAAG,CAAC;QACnD,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBACnC,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI;oBAAE,OAAO,IAAI,CAAC;YACzC,CAAC;YAAC,MAAM,CAAC;gBACP,eAAe;YACjB,CAAC;YACD,MAAM,IAAI,GAAI,KAA6C,CAAC,WAAW,EAAE,IAAI,CAAC;YAC9E,OAAO,8CAA8C,IAAI,IAAI,QAAQ,GAAG,CAAC;QAC3E,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC1B,CAAC;QACD,iBAAiB;QACjB,OAAO,yBAAyB,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,UAAU,CAAC;IACpB,CAAC;AACH,CAAC;AA2BD,wFAAwF;AACxF,MAAM,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAEpD,kHAAkH;AAClH,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,CAAC;QACH,OAAO,KAAK,YAAY,KAAK,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAc,EAAE,QAAQ,GAAG,EAAE;IAClE,MAAM,KAAK,GAAqB,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,IAAI,OAAO,EAAU,CAAC;IACnC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,OAAO,OAAO,IAAI,KAAK,GAAG,QAAQ,EAAE,CAAC;QACnC,+BAA+B;QAC/B,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACpD,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtB,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,mBAAmB;oBACzB,OAAO,EAAE,kDAAkD;oBAC3D,KAAK;iBACN,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACpB,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,KAAK,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC/E,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;YAC7D,MAAM;QACR,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,GAAG,GAAG,OAAgB,CAAC;YAC7B,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACpC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YACtC,MAAM,IAAI,GAAmB;gBAC3B,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBACvC,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBAC7C,KAAK;gBACL,GAAG,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpE,kEAAkE;gBAClE,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC3D,CAAC;YAEF,uCAAuC;YACvC,MAAM,IAAI,GAAG,GAAG,YAAY,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC1E,IAAI,IAAI,IAAI,IAAI,KAAK,UAAU;gBAAE,IAAI,CAAC,IAAI,GAAG,IAA+B,CAAC;YAE7E,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEjB,kCAAkC;YAClC,IAAI,CAAC;gBACH,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC;YACtB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,GAAG,gBAAgB,CAAC;YAC7B,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,aAAa;gBACnB,OAAO,EAAE,OAAO;gBAChB,KAAK;aACN,CAAC,CAAC;YACH,MAAM;QACR,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC;gBAC3B,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC;gBACjC,KAAK;aACN,CAAC,CAAC;YACH,MAAM;QACR,CAAC;QAED,KAAK,EAAE,CAAC;IACV,CAAC;IAED,IAAI,KAAK,IAAI,QAAQ,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE,+CAA+C,QAAQ,EAAE;YAClE,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -52,6 +52,9 @@ export interface ErrorHandlerOptions {
|
|
|
52
52
|
* This can include `requestId` and other relevant debugging information.
|
|
53
53
|
* It reaches the log record only, never the returned error's client-visible
|
|
54
54
|
* `data`; put caller-actionable fields in the thrown `McpError`'s `data`.
|
|
55
|
+
* A context, or its `extra`, whose fields throw when copied — an own getter,
|
|
56
|
+
* a `Proxy` trap — is written as `'[Unreadable]'` under `context` or `extra`
|
|
57
|
+
* rather than failing the call.
|
|
55
58
|
*/
|
|
56
59
|
context?: ErrorContext;
|
|
57
60
|
/**
|
|
@@ -73,8 +76,21 @@ export interface ErrorHandlerOptions {
|
|
|
73
76
|
*/
|
|
74
77
|
errorMapper?: (error: unknown) => Error;
|
|
75
78
|
/**
|
|
76
|
-
*
|
|
77
|
-
*
|
|
79
|
+
* Whether the log record carries stack traces. Defaults to `true`: the
|
|
80
|
+
* record's `extra.stack` is then the throw site's stack — never a context's
|
|
81
|
+
* `extra.stack` — and each stack is written once: a `causeChain` node
|
|
82
|
+
* carrying the record's stack, or the same stack as the node before it, is
|
|
83
|
+
* written without it.
|
|
84
|
+
*
|
|
85
|
+
* `false` makes the record stack-free, as a `RequestCancelled` always is: no
|
|
86
|
+
* `extra.stack`, no `extra.errorData.originalStack`, no `stack` on any
|
|
87
|
+
* `extra.errorData.causeChain` node nor `originalStack` in a node's `data`,
|
|
88
|
+
* and every `Error` in the record — in `errorData`, `input`, or the
|
|
89
|
+
* context's `extra` — written without its `stack`, whether this handler, the
|
|
90
|
+
* thrown `McpError`'s own `data`, or the caller supplied the field. Any other
|
|
91
|
+
* key named `stack` is the caller's data and is written as given. The chain
|
|
92
|
+
* itself stays, each node keeping its other fields. The returned error and
|
|
93
|
+
* the exception recorded on the active span are the same either way.
|
|
78
94
|
*/
|
|
79
95
|
includeStack?: boolean;
|
|
80
96
|
/**
|
|
@@ -97,9 +113,10 @@ export interface ErrorHandlerOptions {
|
|
|
97
113
|
* Level to emit this failure's log record at, in place of `error`.
|
|
98
114
|
*
|
|
99
115
|
* Set by the tool handler factory when the thrown error's `data.reason` names
|
|
100
|
-
* a contract entry declaring one (#380),
|
|
116
|
+
* a contract entry declaring one (#380), to `notice` for the framework's
|
|
101
117
|
* own `invalid_arguments` and `client_capability_missing` refusals when no
|
|
102
|
-
* entry declares one (#567)
|
|
118
|
+
* entry declares one (#567), and to `notice` for a scope check's
|
|
119
|
+
* missing-scope refusal (#585). It moves the level of that one record
|
|
103
120
|
* and adds `mcp.error.severity` to the `mcp.errors.classified` increment;
|
|
104
121
|
* everything else the handler does — the span status, the rebuilt `McpError`,
|
|
105
122
|
* the structured fields — is unchanged. A `RequestCancelled` keeps its own
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/utils/internal/error-handler/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,YAAa,SAAQ,OAAO,CAAC,cAAc,CAAC;IAC3D;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,mBAAmB;IAClC
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/utils/internal/error-handler/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,YAAa,SAAQ,OAAO,CAAC,cAAc,CAAC;IAC3D;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAE7B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,CAAC;IAExC;;;;;;;;;;;;;;;;OAgBG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAClC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,SAAS,EAAE,gBAAgB,CAAC;IAE5B;;;OAGG;IACH,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK,CAAE,SAAQ,gBAAgB;IAC7E;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE5C;;;;;OAKG;IACH,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;CACnE"}
|