import { redactError } from "./redact.js"; /** Неуспешный HTTP-ответ API площадки. */ export class ApiError extends Error { override name = "ApiError"; readonly status: number; readonly code?: string; readonly path: string; constructor(status: number, path: string, message?: string, code?: string) { super(message ?? `HTTP ${status}`); this.status = status; this.path = path; if (code !== undefined) { this.code = code; } } } export interface ToolErrorResult { [key: string]: unknown; isError: true; content: [{ type: "text"; text: string }]; } function textForStatus(status: number | undefined, fallback: string): string { if (status === 401) return "ключ недействителен или отозван"; if (status === 403) return "ключу запрещено выполнять это действие"; if (status === 429) return "превышен лимит частоты запросов, повторите позже"; if (status !== undefined && status >= 500 && status <= 599) { return "сервис openrusrouter.ru временно недоступен"; } return fallback; } /** Ошибку любого вида превращает в результат инструмента MCP; текст всегда проходит redactError. */ export function toToolErrorResult(err: unknown): ToolErrorResult { const r = redactError(err); let text = textForStatus(r.status, r.message); const details = [r.status !== undefined ? `HTTP ${r.status}` : "", r.code ?? "", r.path ?? ""] .filter((s) => s !== "") .join(", "); if (details !== "") { text += ` (${details})`; } return { isError: true, content: [{ type: "text", text }] }; }