Files
skills/docs/devtools/tooling/mcp/src/error-codes/error-codes.md
2026-05-29 08:20:56 +01:00

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) — 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

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 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.