refactor: dedupe extension error formatting

This commit is contained in:
Peter Steinberger
2026-04-07 03:48:34 +01:00
parent 69f4022950
commit 54cd8ed25b
20 changed files with 49 additions and 51 deletions

View File

@@ -1,4 +1,5 @@
import { createSubsystemLogger } from "openclaw/plugin-sdk/core";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import type {
ModelDefinitionConfig,
ModelProviderConfig,
@@ -102,7 +103,7 @@ export async function generateBearerTokenFromIam(params: {
} catch (error) {
log.debug?.("Mantle IAM token generation unavailable", {
region: params.region,
error: error instanceof Error ? error.message : String(error),
error: formatErrorMessage(error),
});
return undefined;
}
@@ -233,7 +234,7 @@ export async function discoverMantleModels(params: {
return models;
} catch (error) {
log.debug?.("Mantle model discovery error", {
error: error instanceof Error ? error.message : String(error),
error: formatErrorMessage(error),
});
return cached?.models ?? [];
}

View File

@@ -223,7 +223,7 @@ function classifyAcpStatusProbeError(params: {
return { status: "stale", reason: "session-init-failed" };
}
const message = params.error instanceof Error ? params.error.message : String(params.error);
const message = formatErrorMessage(params.error);
if (isLegacyMissingSessionError(message)) {
return { status: "stale", reason: "session-missing" };
}

View File

@@ -1,3 +1,4 @@
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input";
import type {
SpeechDirectiveTokenParseContext,
@@ -281,7 +282,7 @@ function parseDirectiveToken(ctx: SpeechDirectiveTokenParseContext) {
} catch (error) {
return {
handled: true,
warnings: [error instanceof Error ? error.message : String(error)],
warnings: [formatErrorMessage(error)],
};
}
}

View File

@@ -1,5 +1,6 @@
import type * as Lark from "@larksuiteoapi/node-sdk";
import { Type } from "@sinclair/typebox";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import type { OpenClawPluginApi } from "../runtime-api.js";
import { listEnabledFeishuAccounts } from "./accounts.js";
import { createFeishuToolClient } from "./tool-account.js";
@@ -579,7 +580,7 @@ export function registerFeishuBitableTools(api: OpenClawPluginApi) {
}),
);
} catch (err) {
return json({ error: err instanceof Error ? err.message : String(err) });
return json({ error: formatErrorMessage(err) });
}
},
}),

View File

@@ -1,4 +1,5 @@
import type * as Lark from "@larksuiteoapi/node-sdk";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import type { OpenClawPluginApi } from "../runtime-api.js";
import { listEnabledFeishuAccounts } from "./accounts.js";
import { FeishuChatSchema, type FeishuChatParams } from "./chat-schema.js";
@@ -181,7 +182,7 @@ export function registerFeishuChatTools(api: OpenClawPluginApi) {
return json({ error: `Unknown action: ${String(p.action)}` });
}
} catch (err) {
return json({ error: err instanceof Error ? err.message : String(err) });
return json({ error: formatErrorMessage(err) });
}
},
},

View File

@@ -4,6 +4,7 @@ import { isAbsolute, resolve } from "node:path";
import { basename } from "node:path";
import type * as Lark from "@larksuiteoapi/node-sdk";
import { Type } from "@sinclair/typebox";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import type { OpenClawPluginApi } from "../runtime-api.js";
import { listEnabledFeishuAccounts } from "./accounts.js";
import { FeishuDocSchema, type FeishuDocParams } from "./doc-schema.js";
@@ -916,7 +917,7 @@ async function createDoc(
});
requesterPermissionAdded = true;
} catch (err) {
requesterPermissionError = err instanceof Error ? err.message : String(err);
requesterPermissionError = formatErrorMessage(err);
}
}
}
@@ -1549,7 +1550,7 @@ export function registerFeishuDocTools(api: OpenClawPluginApi) {
return json({ error: "Unknown action" });
}
} catch (err) {
return json({ error: err instanceof Error ? err.message : String(err) });
return json({ error: formatErrorMessage(err) });
}
},
};
@@ -1573,7 +1574,7 @@ export function registerFeishuDocTools(api: OpenClawPluginApi) {
const result = await listAppScopes(getClient(undefined, ctx.agentAccountId));
return json(result);
} catch (err) {
return json({ error: err instanceof Error ? err.message : String(err) });
return json({ error: formatErrorMessage(err) });
}
},
}),

View File

@@ -1,4 +1,5 @@
import type * as Lark from "@larksuiteoapi/node-sdk";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import type { OpenClawPluginApi } from "../runtime-api.js";
import { listEnabledFeishuAccounts } from "./accounts.js";
import { encodeQuery, extractReplyText, isRecord, readString } from "./comment-shared.js";
@@ -687,7 +688,7 @@ export async function deliverCommentThreadText(
console.warn(
`[feishu_drive] comment metadata preflight failed ` +
`comment=${params.comment_id} file_type=${params.file_type} ` +
`error=${error instanceof Error ? error.message : String(error)}`,
`error=${formatErrorMessage(error)}`,
);
isWholeComment = false;
}

View File

@@ -1,3 +1,4 @@
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import type { ClawdbotConfig } from "../runtime-api.js";
import { resolveFeishuAccount } from "./accounts.js";
import { raceWithTimeoutAndAbort } from "./async.js";
@@ -126,7 +127,7 @@ function safeJsonStringify(value: unknown): string {
return JSON.stringify(value);
} catch (error) {
return JSON.stringify({
error: error instanceof Error ? error.message : String(error),
error: formatErrorMessage(error),
});
}
}

View File

@@ -1,3 +1,4 @@
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { raceWithTimeoutAndAbort } from "./async.js";
import { createFeishuClient, type FeishuClientCredentials } from "./client.js";
import type { FeishuProbeResult } from "./types.js";
@@ -151,7 +152,7 @@ export async function probeFeishu(
{
ok: false,
appId: creds.appId,
error: err instanceof Error ? err.message : String(err),
error: formatErrorMessage(err),
},
PROBE_ERROR_TTL_MS,
);

View File

@@ -1,3 +1,5 @@
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
export function jsonToolResult(data: unknown) {
return {
content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }],
@@ -10,5 +12,5 @@ export function unknownToolActionResult(action: unknown) {
}
export function toolExecutionErrorResult(error: unknown) {
return jsonToolResult({ error: error instanceof Error ? error.message : String(error) });
return jsonToolResult({ error: formatErrorMessage(error) });
}

View File

@@ -4,6 +4,7 @@ import { createRequire } from "node:module";
import path from "node:path";
import { Readable, Writable } from "node:stream";
import { pathToFileURL } from "node:url";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
export type LobsterEnvelope =
| {
@@ -460,10 +461,7 @@ function createFallbackEmbeddedToolRuntime(deps: ToolRuntimeDeps): EmbeddedToolR
});
return normalizeWorkflowOutput(okEnvelope, output);
} catch (error) {
return errorEnvelope(
"runtime_error",
error instanceof Error ? error.message : String(error),
);
return errorEnvelope("runtime_error", formatErrorMessage(error));
}
}
@@ -471,7 +469,7 @@ function createFallbackEmbeddedToolRuntime(deps: ToolRuntimeDeps): EmbeddedToolR
try {
parsed = deps.parsePipeline(String(pipeline));
} catch (error) {
return errorEnvelope("parse_error", error instanceof Error ? error.message : String(error));
return errorEnvelope("parse_error", formatErrorMessage(error));
}
try {
@@ -512,10 +510,7 @@ function createFallbackEmbeddedToolRuntime(deps: ToolRuntimeDeps): EmbeddedToolR
return okEnvelope("ok", output.items, null);
} catch (error) {
return errorEnvelope(
"runtime_error",
error instanceof Error ? error.message : String(error),
);
return errorEnvelope("runtime_error", formatErrorMessage(error));
}
},
@@ -526,7 +521,7 @@ function createFallbackEmbeddedToolRuntime(deps: ToolRuntimeDeps): EmbeddedToolR
try {
payload = deps.decodeResumeToken(token);
} catch (error) {
return errorEnvelope("parse_error", error instanceof Error ? error.message : String(error));
return errorEnvelope("parse_error", formatErrorMessage(error));
}
if (!approved) {
@@ -549,10 +544,7 @@ function createFallbackEmbeddedToolRuntime(deps: ToolRuntimeDeps): EmbeddedToolR
});
return normalizeWorkflowOutput(okEnvelope, output);
} catch (error) {
return errorEnvelope(
"runtime_error",
error instanceof Error ? error.message : String(error),
);
return errorEnvelope("runtime_error", formatErrorMessage(error));
}
}
@@ -603,10 +595,7 @@ function createFallbackEmbeddedToolRuntime(deps: ToolRuntimeDeps): EmbeddedToolR
}
return okEnvelope("ok", output.items, null);
} catch (error) {
return errorEnvelope(
"runtime_error",
error instanceof Error ? error.message : String(error),
);
return errorEnvelope("runtime_error", formatErrorMessage(error));
}
},
};

View File

@@ -18,6 +18,7 @@ import type {
TtsModelOverrideConfig,
TtsProvider,
} from "openclaw/plugin-sdk/config-runtime";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { redactSensitiveText } from "openclaw/plugin-sdk/logging-core";
import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
import type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
@@ -569,7 +570,7 @@ function formatTtsProviderError(provider: TtsProvider, err: unknown): string {
}
function sanitizeTtsErrorForLog(err: unknown): string {
const raw = err instanceof Error ? err.message : String(err);
const raw = formatErrorMessage(err);
return redactSensitiveText(raw).replace(/\r/g, "\\r").replace(/\n/g, "\\n").replace(/\t/g, "\\t");
}

View File

@@ -12,6 +12,7 @@ import type {
TelegramAccountConfig,
TelegramDirectConfig,
} from "openclaw/plugin-sdk/config-runtime";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { clearHistoryEntriesIfEnabled } from "openclaw/plugin-sdk/reply-history";
import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
import type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
@@ -568,9 +569,7 @@ export const dispatchTelegramMessage = async ({
logVerbose("auto-topic-label: SessionKey is absent, skipping first-turn detection");
}
} catch (err) {
logVerbose(
`auto-topic-label: session store error: ${err instanceof Error ? err.message : String(err)}`,
);
logVerbose(`auto-topic-label: session store error: ${formatErrorMessage(err)}`);
}
}
@@ -957,9 +956,7 @@ export const dispatchTelegramMessage = async ({
await bot.api.editForumTopic(chatId, topicThreadId, { name: label });
logVerbose(`auto-topic-label: renamed topic ${chatId}/${topicThreadId}`);
} catch (err) {
logVerbose(
`auto-topic-label: failed: ${err instanceof Error ? err.message : String(err)}`,
);
logVerbose(`auto-topic-label: failed: ${formatErrorMessage(err)}`);
}
})();
}

View File

@@ -3,6 +3,7 @@ import {
type ChannelDoctorEmptyAllowlistAccountContext,
} from "openclaw/plugin-sdk/channel-contract";
import { type OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { inspectTelegramAccount } from "./account-inspect.js";
import { listTelegramAccountIds, resolveTelegramAccount } from "./accounts.js";
import { isNumericTelegramUserId, normalizeTelegramAllowFromEntry } from "./allow-from.js";
@@ -32,10 +33,6 @@ function sanitizeForLog(value: string): string {
return value.replace(/\p{Cc}+/gu, " ").trim();
}
function describeUnknownError(error: unknown): string {
return error instanceof Error ? error.message : String(error);
}
function hasAllowFromEntries(values?: DoctorAllowFromList): boolean {
return Array.isArray(values) && values.some((entry) => String(entry).trim());
}
@@ -170,7 +167,7 @@ export async function maybeRepairTelegramAllowFromUsernames(cfg: OpenClawConfig)
inspected = inspectTelegramAccount({ cfg: resolvedConfig, accountId });
} catch (error) {
tokenResolutionWarnings.push(
`- Telegram account ${accountId}: failed to inspect bot token (${describeUnknownError(error)}).`,
`- Telegram account ${accountId}: failed to inspect bot token (${formatErrorMessage(error)}).`,
);
continue;
}

View File

@@ -3,6 +3,7 @@ import os from "node:os";
import path from "node:path";
import { loadConfig } from "openclaw/plugin-sdk/config-runtime";
import {
formatErrorMessage,
formatThreadBindingDurationLabel,
registerSessionBindingAdapter,
resolveThreadBindingConversationIdFromBindingId,
@@ -607,7 +608,7 @@ export function createTelegramThreadBindingManager(
conversationId = `${result.chatId}:topic:${result.topicId}`;
} catch (err) {
logVerbose(
`telegram: child thread-binding failed for ${chatId}: ${err instanceof Error ? err.message : String(err)}`,
`telegram: child thread-binding failed for ${chatId}: ${formatErrorMessage(err)}`,
);
return null;
}

View File

@@ -3,6 +3,7 @@ import { existsSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { defineBundledChannelEntry } from "openclaw/plugin-sdk/channel-entry-contract";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -171,7 +172,7 @@ export default defineBundledChannelEntry({
content: [
{
type: "text" as const,
text: `Error: ${error instanceof Error ? error.message : String(error)}`,
text: `Error: ${formatErrorMessage(error)}`,
},
],
details: { error: true },

View File

@@ -1,6 +1,7 @@
import { randomUUID } from "node:crypto";
import { mkdir, writeFile } from "node:fs/promises";
import * as path from "node:path";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import {
fetchRemoteMedia,
MAX_IMAGE_BYTES,
@@ -102,9 +103,7 @@ export async function downloadMedia(
originalUrl: url,
};
} catch (error: unknown) {
console.error(
`[tlon-media] Error downloading ${url}: ${error instanceof Error ? error.message : String(error)}`,
);
console.error(`[tlon-media] Error downloading ${url}: ${formatErrorMessage(error)}`);
return null;
}
}

View File

@@ -1,3 +1,4 @@
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { resolveZaloAccount } from "./accounts.js";
import type { ZaloFetch } from "./api.js";
import { sendMessage, sendPhoto } from "./api.js";
@@ -39,7 +40,7 @@ async function runZaloSend(
const result = toZaloSendResult(await send());
return result.ok ? result : { ok: false, error: failureMessage };
} catch (err) {
return { ok: false, error: err instanceof Error ? err.message : String(err) };
return { ok: false, error: formatErrorMessage(err) };
}
}

View File

@@ -1,3 +1,4 @@
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import type { BaseProbeResult } from "../runtime-api.js";
import type { ZcaUserInfo } from "./types.js";
import { getZaloUserInfo } from "./zalo-js.js";
@@ -28,7 +29,7 @@ export async function probeZalouser(
} catch (error) {
return {
ok: false,
error: error instanceof Error ? error.message : String(error),
error: formatErrorMessage(error),
};
}
}

View File

@@ -1,4 +1,5 @@
import { Type } from "@sinclair/typebox";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import type { AnyAgentTool, OpenClawPluginToolContext } from "../runtime-api.js";
import { sendImageZalouser, sendLinkZalouser, sendMessageZalouser } from "./send.js";
import { parseZalouserOutboundTarget } from "./session-route.js";
@@ -189,7 +190,7 @@ export async function executeZalouserTool(
}
} catch (err) {
return json({
error: err instanceof Error ? err.message : String(err),
error: formatErrorMessage(err),
});
}
}