@withpica/mcp-server
Version:
MCP Server for withPICA — enables AI assistants to interact with your withPICA music catalog
60 lines • 3.18 kB
TypeScript
/**
* The parser NEW code should use for the JSON body an API route returned,
* recovered from the message string the SDK folded it into.
*
* ⚠️ This is not yet a consolidation, and saying so would be the exact defect
* this module exists to prevent. Four older extractors are still live and
* untouched — `subscription.ts` `parsePayErrorBody` (:477), `enrichment.ts`
* `extractApiErrorBody` (:1639), and inline `replace`/`match` in
* `duplicates.ts` and `integrity.ts`. Each still misses the `API 404 not
* found:` prefix and the nested body shape described below. Migrating them is
* outstanding; `credits.ts` and `import.ts` read this one.
*
* The SDK's `ApiError` does not carry a structured body — it concatenates the
* response text onto the message. Those extractors disagreed on both halves of
* the job:
*
* - **The prefix.** Routes reach here as `"API request failed: 400 {…}"`,
* `"Authentication failed: 403 {…}"` and `"API 404 not found: {…}"`. An
* anchored `^(?:API request failed|Authentication failed): \d{3}` misses
* the third; that is the shape the recording-credit 404 arrives in.
* - **The body.** Routes emit BOTH a flat shape
* (`{success, error: "…", code: "VALIDATION_ERROR", details: […]}`) and a
* nested one (`{success, error: {code, message, details}}`), and typed
* errors (`typedErrorResponse`, lib/api/typed-error-response.ts, used by
* both `handleRouteError` and `withDualAuth`) add a third
* (`{error: "CODE", message}`, no `code` key). A parser that
* reads `parsed.code` sees `undefined` for every nested body, which is
* what pushed callers back onto regexing the English prose — and prose is
* ambiguous between siblings ("recording not found" vs "person not
* found" both contain "not found"; see FIX_LOG 2026-09-10).
*
* Returning `{}` for an unparseable message is deliberate: every caller then
* reads `code === undefined` and falls back to its generic branch, rather
* than throwing a second time inside a catch.
*/
export interface ApiErrorBody {
/** HTTP status, when the message prefix carried one. */
status?: number;
/** The route's machine code, from any of the three body shapes. */
code?: string;
/** The route's human message, from any of the three body shapes. */
message?: string;
/** Whatever the route put in `details` — shape varies by route. */
details?: unknown;
/**
* Top-level keys the route set BESIDE the error — `remedy` / `reason`
* (withDualAuth's INSUFFICIENT_SCOPE), `person_ids`
* (PERSON_ORG_MISMATCH), `next_tool` / `recording_count`
* (RECORDING_TARGET_REQUIRED). Everything except `success`, `error`,
* `code`, `message` and `details`; absent when there are none. Present
* only when the body parsed whole — a salvaged code carries no siblings.
*/
extra?: Record<string, unknown>;
}
/**
* Recover `{status, code, message, details}` from an SDK error (or a raw
* message string). Never throws.
*/
export declare function parseApiErrorBody(err: unknown): ApiErrorBody;
//# sourceMappingURL=api-error-body.d.ts.map