2.9 KiB
error-codes
(no submodules)
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) — extendsSuaveplanError<MCPCode>so callers get the cause-chain, redaction, OTel adapter, and i18n resolver hook for free. - Type-safe
codediscriminator — noinstanceofrequired. - Public constructors delegate to
superper@suaveplan/errorpolicy.
Usage: Basic Example
import { MCP_CODES, MCPError } from "@suaveplan/mcp/error-codes";
throw new MCPError(MCP_CODES.NOT_FOUND, 'Tool "echo" not found');
Usage: Advanced Example
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 ofMCP_CODES.MCPError extends SuaveplanError<MCPCode>— constructor:(code, message, options?).MCPTransportError extends MCPError— same constructor; thrown when the underlying transport rejects asend(TRANSPORT_CLOSED) or surfaces an upstream failure (TRANSPORT_ERROR).MCPProtocolError extends MCPError— thrown forPROTOCOL_INVALIDandPROTOCOL_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.