diff --git a/src/cli/nodes-cli/register.status.ts b/src/cli/nodes-cli/register.status.ts index 892267f2906..a97c0aaecb4 100644 --- a/src/cli/nodes-cli/register.status.ts +++ b/src/cli/nodes-cli/register.status.ts @@ -1,4 +1,5 @@ import type { Command } from "commander"; +import { formatErrorMessage } from "../../infra/errors.js"; import { formatTimeAgo } from "../../infra/format-time/format-relative.ts"; import { defaultRuntime } from "../../runtime.js"; import { getTerminalTableWidth, renderTable } from "../../terminal/table.js"; @@ -99,7 +100,7 @@ function parseSinceMs(raw: unknown, label: string): number | undefined { try { return parseDurationMs(value); } catch (err) { - const message = err instanceof Error ? err.message : String(err); + const message = formatErrorMessage(err); defaultRuntime.error(`${label}: ${message}`); defaultRuntime.exit(1); return undefined; diff --git a/src/cli/ports.ts b/src/cli/ports.ts index fd829bf21db..cc01e9c57de 100644 --- a/src/cli/ports.ts +++ b/src/cli/ports.ts @@ -1,5 +1,6 @@ import { execFileSync } from "node:child_process"; import { createServer } from "node:net"; +import { formatErrorMessage } from "../infra/errors.js"; import { resolveLsofCommandSync } from "../infra/ports-lsof.js"; import { tryListenOnPort } from "../infra/ports-probe.js"; import { sleep } from "../utils.js"; @@ -64,7 +65,7 @@ function isRecoverableLsofError(err: unknown): boolean { if (code === "ENOENT" || code === "EACCES" || code === "EPERM") { return true; } - const message = err instanceof Error ? err.message : String(err); + const message = formatErrorMessage(err); return /lsof.*(permission denied|not permitted|operation not permitted|eacces|eperm)/i.test( message, ); diff --git a/src/commands/doctor-gateway-health.ts b/src/commands/doctor-gateway-health.ts index 9016fba1d8f..0544d6e2dbd 100644 --- a/src/commands/doctor-gateway-health.ts +++ b/src/commands/doctor-gateway-health.ts @@ -2,6 +2,7 @@ import type { OpenClawConfig } from "../config/config.js"; import { buildGatewayConnectionDetails, callGateway } from "../gateway/call.js"; import type { DoctorMemoryStatusPayload } from "../gateway/server-methods/doctor.js"; import { collectChannelStatusIssues } from "../infra/channels-status-issues.js"; +import { formatErrorMessage } from "../infra/errors.js"; import type { RuntimeEnv } from "../runtime.js"; import { note } from "../terminal/note.js"; import { formatHealthCheckFailure } from "./health-format.js"; @@ -82,7 +83,7 @@ export async function probeGatewayMemoryStatus(params: { error: payload.embedding.error, }; } catch (err) { - const message = err instanceof Error ? err.message : String(err); + const message = formatErrorMessage(err); return { checked: true, ready: false, diff --git a/src/flows/channel-setup.ts b/src/flows/channel-setup.ts index 9937418251a..563d5d8b093 100644 --- a/src/flows/channel-setup.ts +++ b/src/flows/channel-setup.ts @@ -26,6 +26,7 @@ import type { import type { ChannelChoice } from "../commands/onboard-types.js"; import { isChannelConfigured } from "../config/channel-configured.js"; import type { OpenClawConfig } from "../config/config.js"; +import { formatErrorMessage } from "../infra/errors.js"; import { enablePluginInConfig } from "../plugins/enable.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../routing/session-key.js"; import type { RuntimeEnv } from "../runtime.js"; @@ -68,7 +69,7 @@ export async function runCollectedChannelOnboardingPostWriteHooks(params: { try { await hook.run({ cfg: params.cfg, runtime: params.runtime }); } catch (err) { - const message = err instanceof Error ? err.message : String(err); + const message = formatErrorMessage(err); params.runtime.error( `Channel ${hook.channel} post-setup warning for "${hook.accountId}": ${message}`, ); diff --git a/src/hooks/bundled/command-logger/handler.ts b/src/hooks/bundled/command-logger/handler.ts index e9ee6527551..b923e04605b 100644 --- a/src/hooks/bundled/command-logger/handler.ts +++ b/src/hooks/bundled/command-logger/handler.ts @@ -27,6 +27,7 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { resolveStateDir } from "../../../config/paths.js"; +import { formatErrorMessage } from "../../../infra/errors.js"; import { createSubsystemLogger } from "../../../logging/subsystem.js"; import type { HookHandler } from "../../hooks.js"; @@ -60,7 +61,7 @@ const logCommand: HookHandler = async (event) => { await fs.appendFile(logFile, logLine, "utf-8"); } catch (err) { - const message = err instanceof Error ? err.message : String(err); + const message = formatErrorMessage(err); log.error(`Failed to log command: ${message}`); } }; diff --git a/src/hooks/internal-hooks.ts b/src/hooks/internal-hooks.ts index 224fe32f797..dba7bf4985d 100644 --- a/src/hooks/internal-hooks.ts +++ b/src/hooks/internal-hooks.ts @@ -10,6 +10,7 @@ import type { CliDeps } from "../cli/deps.js"; import type { OpenClawConfig } from "../config/config.js"; import type { SessionEntry } from "../config/sessions.js"; import type { SessionsPatchParams } from "../gateway/protocol/index.js"; +import { formatErrorMessage } from "../infra/errors.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { resolveGlobalSingleton } from "../shared/global-singleton.js"; @@ -299,7 +300,7 @@ export async function triggerInternalHook(event: InternalHookEvent): Promise