UNPKG

@withpica/mcp-server

Version:

MCP Server for withPICA — enables AI assistants to interact with your withPICA music catalog

44 lines • 2.43 kB
/** * Typed tool-error envelope for executors that catch internally. * * An executor that swallows a throw and returns * `formatAsText({ error: "Failed to …" })` produces a result with no * `isError`, so the dispatcher and the client both read it as a SUCCESS whose * payload happens to contain the word "error", and the prose sentence sits in * the field a machine reads as a code. * * `typedError` gives an internal catch the `{ error, message }` + `isError` * shape the dispatcher's own catch emits via `formatError` * (mcp-server-shared/mcp-utils/src/errors.ts). * * ⚠️ What the `error` code actually buys, and only this: * `ToolRegistry.execute` (`./index.ts`) passes an `isError` RESULT to * `extractErrorAttribution` (`./index.ts`, exported), which reads * `envelope.error_code ?? envelope.error` off the first text block and writes * it to `mcp_audit_log.error_code`. Without a JSON envelope that column is * NULL and the ops_issues pipeline, which groups on the code, cannot see the * failure. Pinned by `src/__tests__/tools/extract-error-attribution.test.ts` * ("accepts the formatError shape (`error` + `message` keys)"). * * ⚠️ It does NOT reach `getRecoveryHint`. That has exactly one call site — * `ToolRegistry.execute`'s `catch` — so hints attach to THROWN errors only. A * returned `isError` result, however well typed, gets no `suggestion` or * `next_tool`. Making a hint fire means letting the error throw, not naming * its code here. * * Enforced by the `typed error envelopes` describe blocks in * `src/__tests__/tools/{notifications,telegram,credits,import}.test.ts` — they * assert `isError === true` and a SCREAMING_SNAKE `error` for every executor * that uses this helper. Nothing stops a NEW executor from hand-rolling the * old shape; those tests cover the executors listed, not the whole surface. */ import type { ToolResult } from "./index.js"; /** * @param code SCREAMING_SNAKE machine code — no spaces. * @param message Human-readable cause, safe to show the user. * @param extra Optional additional body fields (e.g. `sent: false`). Spread * FIRST so it can never overwrite `error` or `message` — the * two fields `extractErrorAttribution` reads. */ export declare function typedError(code: string, message: string, extra?: Record<string, unknown>): ToolResult; //# sourceMappingURL=error-envelope.d.ts.map