UNPKG

kestrel.markets

Version:

A typed, token-efficient language + runtime for agentic trading: agents author bounded plans, the runtime fires them at the tick. CLI + typed library + MCP server.

126 lines (123 loc) 3.47 kB
// src/cli/errors.ts var EXIT = { OK: 0, GENERIC: 1, USAGE: 2, NOT_FOUND: 3, RUNTIME_UNAVAILABLE: 4, PAYMENT_REQUIRED: 5, HANDSHAKE: 6, PAPER_REFUSED: 7, SIGINT: 130 }; class CliError extends Error { name = "CliError"; code; exit; hint; problem; constructor(o) { super(o.message); this.code = o.code; this.exit = o.exit; if (o.hint !== undefined) this.hint = o.hint; if (o.problem !== undefined) this.problem = o.problem; } } var RED = "\x1B[31m"; var DIM = "\x1B[2m"; var RESET = "\x1B[0m"; var CONNECTION_ERRNOS = new Set([ "ENOTFOUND", "EAI_AGAIN", "ECONNREFUSED", "ECONNRESET", "ECONNABORTED", "ETIMEDOUT", "EHOSTUNREACH", "ENETUNREACH", "ENETDOWN", "EPIPE", "EAI_FAIL", "UND_ERR_CONNECT_TIMEOUT", "UND_ERR_SOCKET", "ConnectionRefused", "ConnectionClosed", "ConnectionTimeout", "FailedToOpenSocket", "DNSError" ]); function errCode(e) { if (typeof e === "object" && e !== null && "code" in e) { const c = e.code; if (typeof c === "string") return c; } return; } function asConnectionError(e, base) { if (e instanceof CliError) return null; const cause = typeof e === "object" && e !== null ? e.cause : undefined; const code = errCode(e) ?? errCode(cause); const isFetchTransport = code !== undefined && CONNECTION_ERRNOS.has(code) || e instanceof TypeError && /fetch failed|failed to fetch|unable to connect|failed to connect/i.test(e.message); if (!isFetchTransport) return null; const outer = e instanceof Error ? e.message : String(e); const inner = cause instanceof Error ? cause.message : undefined; const parts = [outer]; if (inner !== undefined && inner !== outer) parts.push(inner); else if (code !== undefined && !outer.includes(code)) parts.push(code); const detail = parts.join(" — "); const where = base !== undefined && base !== "" ? ` reaching ${base}` : ""; return new CliError({ code: "NETWORK_UNAVAILABLE", exit: EXIT.RUNTIME_UNAVAILABLE, message: `network unavailable${where}: ${detail}`, hint: "check your network connection and the API base (--api / KESTREL_API)" }); } function fail(ctx, err) { const isCli = err instanceof CliError; const code = isCli ? err.code : "GENERIC"; const exit = isCli ? err.exit : EXIT.GENERIC; const message = err instanceof Error ? err.message : String(err); const hint = isCli ? err.hint : undefined; const problem = isCli ? err.problem : undefined; if (ctx.mode === "json") { const obj = { error: { code, message } }; if (hint !== undefined) obj.error.hint = hint; if (problem !== undefined) obj.error.problem = problem; process.stderr.write(JSON.stringify(obj) + ` `); } else if (ctx.mode === "text") { let line = `error code=${code} message=${message}`; if (hint !== undefined) line += ` hint=${hint}`; process.stderr.write(line + ` `); } else { const emsg = ctx.color ? `${RED}error:${RESET} ${message}` : `error: ${message}`; process.stderr.write(emsg + ` `); if (hint !== undefined) { const hmsg = ctx.color ? `${DIM}hint: ${hint}${RESET}` : `hint: ${hint}`; process.stderr.write(hmsg + ` `); } } if (!isCli && process.env.KESTREL_DEBUG === "1" && err instanceof Error && err.stack !== undefined) { process.stderr.write(err.stack + ` `); } return exit; } export { EXIT, CliError, asConnectionError, fail };