refactor: dedupe script error formatting

This commit is contained in:
Peter Steinberger
2026-04-07 04:09:30 +01:00
parent bbe9b7ba15
commit 7dc085890e
16 changed files with 46 additions and 21 deletions

View File

@@ -6,6 +6,7 @@ import { homedir } from "node:os";
import path from "node:path";
import { createInterface } from "node:readline";
import { fileURLToPath, pathToFileURL } from "node:url";
import { formatErrorMessage } from "../src/infra/errors.ts";
interface TranslationMap {
[key: string]: string | TranslationMap;
@@ -1317,6 +1318,6 @@ async function main() {
}
await main().catch((error) => {
console.error(error instanceof Error ? error.message : String(error));
console.error(formatErrorMessage(error));
process.exit(1);
});

View File

@@ -6,6 +6,7 @@ import { randomUUID } from "node:crypto";
import fs from "node:fs/promises";
import path from "node:path";
import { promisify } from "node:util";
import { formatErrorMessage } from "../../src/infra/errors.ts";
function writeStdoutLine(message: string): void {
process.stdout.write(`${message}\n`);
@@ -540,7 +541,7 @@ async function run(): Promise<SuccessResult | FailureResult> {
ok: false,
stage: "validation",
smokeId: "n/a",
error: err instanceof Error ? err.message : String(err),
error: formatErrorMessage(err),
};
}
@@ -672,7 +673,7 @@ async function run(): Promise<SuccessResult | FailureResult> {
ok: false,
stage: setupStage,
smokeId,
error: err instanceof Error ? err.message : String(err),
error: formatErrorMessage(err),
};
}
@@ -830,7 +831,7 @@ const result = await run().catch(
ok: false,
stage: "unexpected",
smokeId: "n/a",
error: err instanceof Error ? err.message : String(err),
error: formatErrorMessage(err),
}),
);

View File

@@ -6,6 +6,7 @@ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"
import { WebSocket } from "ws";
import { z } from "zod";
import { PROTOCOL_VERSION } from "../../src/gateway/protocol/index.ts";
import { formatErrorMessage } from "../../src/infra/errors.ts";
import { rawDataToString } from "../../src/infra/ws.ts";
export const ClaudeChannelNotificationSchema = z.object({
@@ -379,7 +380,7 @@ export async function maybeApprovePendingBridgePairing(
pending?: Array<{ requestId?: string; role?: string }>;
}>("device.pair.list", {});
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
const message = formatErrorMessage(error);
if (message.includes("missing scope: operator.pairing")) {
return false;
}

View File

@@ -156,6 +156,8 @@ const timeoutMs = Number(timeoutRaw) > 0 ? Number(timeoutRaw) : 45000;
const gatewayCallTimeoutMs = Math.max(15000, Math.min(timeoutMs, 90000));
const retryableGatewayErrorPattern =
/gateway ws open timeout|gateway connect timeout|gateway closed|ECONNREFUSED|socket hang up|gateway timeout after/i;
const formatErrorMessage = (error) =>
error instanceof Error ? error.message || error.name || "Error" : String(error);
const gatewayArgs = [
entry,
"gateway",
@@ -188,7 +190,7 @@ const callGatewayOnce = (method, params) => {
};
const isRetryableGatewayError = (error) =>
retryableGatewayErrorPattern.test(error instanceof Error ? error.message : String(error));
retryableGatewayErrorPattern.test(formatErrorMessage(error));
const extractText = (messageLike) => {
if (!messageLike || typeof messageLike !== "object") {
@@ -316,7 +318,7 @@ async function main() {
}
main().catch((error) => {
console.error(error instanceof Error ? error.message : String(error));
console.error(formatErrorMessage(error));
process.exit(1);
});
NODE

View File

@@ -1,5 +1,6 @@
import { fetchFirecrawlContent } from "../extensions/firecrawl/api.ts";
import { extractReadableContent } from "../src/agents/tools/web-tools.js";
import { formatErrorMessage } from "../src/infra/errors.ts";
const DEFAULT_URLS = [
"https://en.wikipedia.org/wiki/Web_scraping",
@@ -88,7 +89,7 @@ async function run() {
}
} catch (error) {
localStatus = "error";
localError = error instanceof Error ? error.message : String(error);
localError = formatErrorMessage(error);
}
console.log(`local: ${localStatus} len=${localText.length} title=${truncate(localTitle, 80)}`);
@@ -125,7 +126,7 @@ async function run() {
console.log(`firecrawl sample: ${truncate(firecrawl.text)}`);
}
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
const message = formatErrorMessage(error);
console.log(`firecrawl: error ${message}`);
}
}

View File

@@ -0,0 +1,6 @@
export function formatErrorMessage(error) {
if (error instanceof Error) {
return error.message || error.name || "Error";
}
return String(error);
}

View File

@@ -5,6 +5,7 @@ import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { pathToFileURL } from "node:url";
import { formatErrorMessage } from "../src/infra/errors.ts";
import { BUNDLED_RUNTIME_SIDECAR_PATHS } from "../src/plugins/runtime-sidecar-paths.ts";
import { parseReleaseVersion, resolveNpmCommandInvocation } from "./openclaw-npm-release-check.ts";
@@ -141,9 +142,7 @@ if (entrypoint !== null && import.meta.url === entrypoint) {
try {
main();
} catch (error) {
console.error(
`openclaw-npm-postpublish-verify: ${error instanceof Error ? error.message : String(error)}`,
);
console.error(`openclaw-npm-postpublish-verify: ${formatErrorMessage(error)}`);
process.exitCode = 1;
}
}

View File

@@ -3,6 +3,7 @@
import { spawnSync } from "node:child_process";
import { existsSync, readdirSync } from "node:fs";
import { pathToFileURL } from "node:url";
import { formatErrorMessage } from "../src/infra/errors.ts";
const skipPrepackPreparedEnv = "OPENCLAW_PREPACK_PREPARED";
const requiredPreparedPathGroups = [
@@ -90,7 +91,7 @@ function ensurePreparedArtifacts(): void {
console.error(`prepack: ${error}`);
}
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
const message = formatErrorMessage(error);
console.error(`prepack: failed to verify prepared artifacts: ${message}`);
}

View File

@@ -4,6 +4,7 @@ import { spawn } from "node:child_process";
import { existsSync, mkdtempSync, readdirSync, rmSync, writeFileSync } from "node:fs";
import os from "node:os";
import path from "node:path";
import { formatErrorMessage } from "./lib/error-format.mjs";
const DEFAULT_CONCURRENCY = 6;
const DEFAULT_TIMEOUT_MS = 90_000;
@@ -354,6 +355,6 @@ async function main() {
try {
await main();
} catch (error) {
console.error(`[extension-memory] ${error instanceof Error ? error.message : String(error)}`);
console.error(`[extension-memory] ${formatErrorMessage(error)}`);
process.exit(1);
}

View File

@@ -3,6 +3,7 @@ import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { pathToFileURL } from "node:url";
import { formatErrorMessage } from "./lib/error-format.mjs";
export function parseArgs(argv) {
const args = {
@@ -106,7 +107,7 @@ if (isMain) {
try {
main();
} catch (error) {
console.error(error instanceof Error ? error.message : String(error));
console.error(formatErrorMessage(error));
process.exit(1);
}
}

View File

@@ -1,5 +1,6 @@
import { DatabaseSync } from "node:sqlite";
import { load, getLoadablePath } from "sqlite-vec";
import { formatErrorMessage } from "./lib/error-format.mjs";
function vec(values) {
return Buffer.from(new Float32Array(values).buffer);
@@ -10,7 +11,7 @@ const db = new DatabaseSync(":memory:", { allowExtension: true });
try {
load(db);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
const message = formatErrorMessage(err);
console.error("sqlite-vec load failed:");
console.error(message);
console.error("expected extension path:", getLoadablePath());

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env node
import { formatErrorMessage } from "./lib/error-format.mjs";
import { resolveExtensionTestPlan } from "./lib/extension-test-plan.mjs";
import { isDirectScriptRun, runVitestBatch } from "./lib/vitest-batch-runner.mjs";
@@ -31,7 +32,7 @@ async function run() {
plan = resolveExtensionTestPlan({ cwd: process.cwd(), targetArg });
} catch (error) {
printUsage();
console.error(error instanceof Error ? error.message : String(error));
console.error(formatErrorMessage(error));
process.exit(1);
}

View File

@@ -4,6 +4,7 @@ import { spawn, type ChildProcess } from "node:child_process";
import { createRequire } from "node:module";
import { pathToFileURL } from "node:url";
import { collectProviderApiKeys } from "../src/agents/live-auth-keys.js";
import { formatErrorMessage } from "../src/infra/errors.ts";
import { loadShellEnvFallback } from "../src/infra/shell-env.js";
import { getProviderEnvVars } from "../src/secrets/provider-env-vars.js";
type SpawnPnpmRunner = (params: {
@@ -365,7 +366,7 @@ if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
runCli(process.argv.slice(2))
.then((code) => process.exit(code))
.catch((error) => {
console.error(error instanceof Error ? error.message : String(error));
console.error(formatErrorMessage(error));
process.exit(1);
});
}

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env node
import path from "node:path";
import { formatErrorMessage } from "../src/infra/errors.ts";
import { analyzeTopology } from "./lib/ts-topology/analyze.js";
import { renderTextReport } from "./lib/ts-topology/reports.js";
import {
@@ -136,7 +137,7 @@ export async function main(argv: string[], io: IoLike = process): Promise<number
try {
options = parseArgs(argv);
} catch (error) {
io.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
io.stderr.write(`${formatErrorMessage(error)}\n`);
return 1;
}
@@ -158,7 +159,7 @@ export async function main(argv: string[], io: IoLike = process): Promise<number
io.stdout.write(`${renderTextReport(envelope, options.limit)}\n`);
return 0;
} catch (error) {
io.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
io.stderr.write(`${formatErrorMessage(error)}\n`);
return 1;
}
}