mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
* refactor: expand acp core package * chore: drop acp core package symlink * fix: keep acp core dependency graph stable * fix: add acp core tsconfig subpaths * fix: sync acp core boundary path artifacts * fix: use kysely for cron run-log queries * fix: resolve acp core subpaths in loaders
98 lines
3.6 KiB
JavaScript
98 lines
3.6 KiB
JavaScript
import { redactSensitiveText, stringifyNonErrorCause } from "../error-format.mjs";
|
|
//#region src/runtime/errors.ts
|
|
const ACP_ERROR_CODES = [
|
|
"ACP_BACKEND_MISSING",
|
|
"ACP_BACKEND_UNAVAILABLE",
|
|
"ACP_BACKEND_UNSUPPORTED_CONTROL",
|
|
"ACP_DISPATCH_DISABLED",
|
|
"ACP_INVALID_RUNTIME_OPTION",
|
|
"ACP_SESSION_INIT_FAILED",
|
|
"ACP_TURN_FAILED"
|
|
];
|
|
const ACP_ERROR_CODE_SET = new Set(ACP_ERROR_CODES);
|
|
var AcpRuntimeError = class extends Error {
|
|
constructor(code, message, options) {
|
|
super(message);
|
|
this.name = "AcpRuntimeError";
|
|
this.code = code;
|
|
this.cause = options?.cause;
|
|
}
|
|
};
|
|
function getForeignAcpRuntimeError(value) {
|
|
if (!(value instanceof Error)) return null;
|
|
const code = value.code;
|
|
if (typeof code !== "string" || !ACP_ERROR_CODE_SET.has(code)) return null;
|
|
return {
|
|
code,
|
|
message: value.message
|
|
};
|
|
}
|
|
function readAcpRequestErrorDetails(value) {
|
|
if (typeof value.code !== "number") return;
|
|
const data = value.data;
|
|
if (!data || typeof data !== "object") return;
|
|
const details = data.details;
|
|
if (details === void 0 || details === null) return;
|
|
const rendered = redactSensitiveText(stringifyNonErrorCause(details)).trim();
|
|
return rendered.length > 0 ? rendered : void 0;
|
|
}
|
|
function messageWithAcpRequestErrorDetails(error) {
|
|
const details = readAcpRequestErrorDetails(error);
|
|
if (!details || error.message.includes(details)) return error.message;
|
|
return `${error.message}: ${details}`;
|
|
}
|
|
function isAcpRuntimeError(value) {
|
|
return value instanceof AcpRuntimeError || getForeignAcpRuntimeError(value) !== null;
|
|
}
|
|
function toAcpRuntimeError(params) {
|
|
if (params.error instanceof AcpRuntimeError) return params.error;
|
|
const foreignAcpRuntimeError = getForeignAcpRuntimeError(params.error);
|
|
if (foreignAcpRuntimeError) return new AcpRuntimeError(foreignAcpRuntimeError.code, foreignAcpRuntimeError.message, { cause: params.error });
|
|
if (params.error instanceof Error) return new AcpRuntimeError(params.fallbackCode, messageWithAcpRequestErrorDetails(params.error), { cause: params.error });
|
|
return new AcpRuntimeError(params.fallbackCode, params.fallbackMessage, { cause: params.error });
|
|
}
|
|
/**
|
|
* Render an error and its `.cause` chain as a single human-readable line for
|
|
* logs, lifecycle events, and tool results. Format is
|
|
* `Name [code]: message <- Name [code]: message <- ...`. Number codes also
|
|
* appear, so JSON-RPC error codes like `-32603` survive into surfaces that
|
|
* downstream consumers see (gateway logs, telegram replies, tool_result text).
|
|
*
|
|
* Depth is capped to defend against self-referential `.cause` cycles.
|
|
*/
|
|
function formatAcpErrorChain(error) {
|
|
if (!(error instanceof Error)) return redactSensitiveText(String(error));
|
|
const segments = [renderSingleError(error)];
|
|
let current = error.cause;
|
|
let depth = 0;
|
|
while (current !== void 0 && current !== null && depth < 8) {
|
|
if (current instanceof Error) {
|
|
segments.push(renderSingleError(current));
|
|
current = current.cause;
|
|
} else {
|
|
segments.push(stringifyNonErrorCause(current));
|
|
current = void 0;
|
|
}
|
|
depth += 1;
|
|
}
|
|
return redactSensitiveText(segments.join(" <- "));
|
|
}
|
|
function renderSingleError(error) {
|
|
const codeValue = error.code;
|
|
const codeSuffix = typeof codeValue === "string" || typeof codeValue === "number" ? ` [${codeValue}]` : "";
|
|
return `${error.name}${codeSuffix}: ${error.message}`;
|
|
}
|
|
async function withAcpRuntimeErrorBoundary(params) {
|
|
try {
|
|
return await params.run();
|
|
} catch (error) {
|
|
throw toAcpRuntimeError({
|
|
error,
|
|
fallbackCode: params.fallbackCode,
|
|
fallbackMessage: params.fallbackMessage
|
|
});
|
|
}
|
|
}
|
|
//#endregion
|
|
export { ACP_ERROR_CODES, AcpRuntimeError, formatAcpErrorChain, isAcpRuntimeError, toAcpRuntimeError, withAcpRuntimeErrorBoundary };
|