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
JavaScript
// 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 };