first commit
This commit is contained in:
56
docs/devtools/tooling/mcp/src/error-codes/error-codes.md
Normal file
56
docs/devtools/tooling/mcp/src/error-codes/error-codes.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# error-codes
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
`@suaveplan/mcp` raises three typed error classes — `MCPError`, `MCPTransportError`, and `MCPProtocolError` — for every failure mode the package exposes. Codes are registered via `defineCodes` from `@suaveplan/error`, giving consumers a stable fully-qualified string (e.g. `"MCP.UNAUTHORIZED"`) they can pattern-match on without `instanceof` chains. Discriminating on `error.code` keeps consumers, retries, dashboards, and i18n catalogues in lockstep with the package no matter how the class hierarchy evolves.
|
||||
|
||||
## Features
|
||||
|
||||
- Stable code registry: 15 codes spanning protocol, transport, lifecycle, registration, and handler failures.
|
||||
- Three classes (`MCPError`, `MCPTransportError`, `MCPProtocolError`) — extends `SuaveplanError<MCPCode>` so callers get the cause-chain, redaction, OTel adapter, and i18n resolver hook for free.
|
||||
- Type-safe `code` discriminator — no `instanceof` required.
|
||||
- Public constructors delegate to `super` per `@suaveplan/error` policy.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { MCP_CODES, MCPError } from "@suaveplan/mcp/error-codes";
|
||||
|
||||
throw new MCPError(MCP_CODES.NOT_FOUND, 'Tool "echo" not found');
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { MCP_CODES, MCPError, MCPTransportError } from "@suaveplan/mcp";
|
||||
|
||||
try {
|
||||
await client.callTool("slow", { ms: 10_000 }, { timeoutMs: 100 });
|
||||
} catch (error) {
|
||||
if (error instanceof MCPTransportError) {
|
||||
metrics.record("mcp.transport_error");
|
||||
return;
|
||||
}
|
||||
if (error instanceof MCPError && error.code === MCP_CODES.TIMEOUT) {
|
||||
logger.warn("call timed out", { code: error.code });
|
||||
return;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `MCP_CODES` — frozen object whose values are the fully-qualified code strings (`"MCP.<LEAF>"`).
|
||||
- `MCPCode` — string-literal union of every value of `MCP_CODES`.
|
||||
- `MCPError extends SuaveplanError<MCPCode>` — constructor: `(code, message, options?)`.
|
||||
- `MCPTransportError extends MCPError` — same constructor; thrown when the underlying transport rejects a `send` (`TRANSPORT_CLOSED`) or surfaces an upstream failure (`TRANSPORT_ERROR`).
|
||||
- `MCPProtocolError extends MCPError` — thrown for `PROTOCOL_INVALID` and `PROTOCOL_VERSION_MISMATCH`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The registry is declared via `defineCodes("MCP", [...] as const)` which asserts the array is a literal tuple and produces a `Record<Key, "MCP.Key">` mapping. Adding a code anywhere except the tuple breaks both the type and the runtime registry — the type-system guarantees the two stay in sync. Every registered code is reachable from a real call site exercised by a test (see `error-codes.test.ts`). The constructor delegates to `SuaveplanError`'s protected constructor; subclasses keep `name` distinct so logs and traces can still distinguish transport from protocol failures even though they share the typed-code surface.
|
||||
Reference in New Issue
Block a user