Skip to content

Commit 80805ad

Browse files
committed
refactor(agents): share error normalization helpers
1 parent 86ea382 commit 80805ad

11 files changed

Lines changed: 26 additions & 171 deletions

src/agents/agent-bundle-mcp-runtime.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { redactSensitiveUrlLikeString } from "@openclaw/net-policy/redact-sensit
1515
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
1616
import { Compile } from "typebox/compile";
1717
import type { OpenClawConfig } from "../config/types.openclaw.js";
18+
import { toErrorObject } from "../infra/errors.js";
1819
import { logWarn } from "../logger.js";
1920
import type { PluginManifestRegistry } from "../plugins/manifest-registry.js";
2021
import { resolveGlobalSingleton } from "../shared/global-singleton.js";
@@ -204,7 +205,7 @@ function connectWithTimeout(
204205
},
205206
(error: unknown) => {
206207
clearTimeout(timer);
207-
reject(toLintErrorObject(error, "Non-Error rejection"));
208+
reject(toErrorObject(error, "Non-Error rejection"));
208209
},
209210
);
210211
});
@@ -1144,17 +1145,3 @@ export const testing = {
11441145
resolveSessionMcpRuntimeIdleTtlMs,
11451146
};
11461147
export { testing as __testing };
1147-
1148-
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
1149-
if (value instanceof Error) {
1150-
return value;
1151-
}
1152-
if (typeof value === "string") {
1153-
return new Error(value);
1154-
}
1155-
const error = new Error(fallbackMessage, { cause: value });
1156-
if ((typeof value === "object" && value !== null) || typeof value === "function") {
1157-
Object.assign(error, value);
1158-
}
1159-
return error;
1160-
}

src/agents/agent-tools.read.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import path from "node:path";
88
import { URL } from "node:url";
99
import { detectMime } from "@openclaw/media-core/mime";
1010
import { isWindowsDrivePath } from "../infra/archive-path.js";
11+
import { toErrorObject } from "../infra/errors.js";
1112
import {
1213
canonicalPathFromExistingAncestor,
1314
root as fsRoot,
@@ -737,7 +738,7 @@ async function assertSandboxPathWithinAnyRoot(params: {
737738
firstRootEscapeError ??= error;
738739
}
739740
}
740-
throw toLintErrorObject(
741+
throw toErrorObject(
741742
firstRootEscapeError ?? new Error("Path guard has no configured roots."),
742743
"Non-Error thrown",
743744
);
@@ -1127,17 +1128,3 @@ function createFsAccessError(code: string, filePath: string): NodeJS.ErrnoExcept
11271128
error.code = code;
11281129
return error;
11291130
}
1130-
1131-
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
1132-
if (value instanceof Error) {
1133-
return value;
1134-
}
1135-
if (typeof value === "string") {
1136-
return new Error(value);
1137-
}
1138-
const error = new Error(fallbackMessage, { cause: value });
1139-
if ((typeof value === "object" && value !== null) || typeof value === "function") {
1140-
Object.assign(error, value);
1141-
}
1142-
return error;
1143-
}

src/agents/anthropic-transport-stream.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
import { readResponseTextSnippet } from "@openclaw/media-core/read-response-with-limit";
77
import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce";
8+
import { toErrorObject } from "../infra/errors.js";
89
import { getEnvApiKey } from "../llm/env-api-keys.js";
910
import { calculateCost, clampThinkingLevel } from "../llm/model-utils.js";
1011
import {
@@ -681,7 +682,7 @@ function readAnthropicSseChunk(
681682
}
682683
settled = true;
683684
signal.removeEventListener("abort", onAbort);
684-
reject(toLintErrorObject(error, "Non-Error rejection"));
685+
reject(toErrorObject(error, "Non-Error rejection"));
685686
},
686687
);
687688
});
@@ -1604,17 +1605,3 @@ export function createAnthropicMessagesTransportStreamFn(): StreamFn {
16041605
return eventStream as ReturnType<StreamFn>;
16051606
};
16061607
}
1607-
1608-
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
1609-
if (value instanceof Error) {
1610-
return value;
1611-
}
1612-
if (typeof value === "string") {
1613-
return new Error(value);
1614-
}
1615-
const error = new Error(fallbackMessage, { cause: value });
1616-
if ((typeof value === "object" && value !== null) || typeof value === "function") {
1617-
Object.assign(error, value);
1618-
}
1619-
return error;
1620-
}

src/agents/command/delivery.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { createReplyPrefixContext } from "../../channels/reply-prefix.js";
1515
import { createOutboundSendDeps, type CliDeps } from "../../cli/outbound-send-deps.js";
1616
import type { SessionEntry } from "../../config/sessions.js";
1717
import type { OpenClawConfig } from "../../config/types.openclaw.js";
18-
import { formatErrorMessage } from "../../infra/errors.js";
18+
import { formatErrorMessage, toErrorObject } from "../../infra/errors.js";
1919
import {
2020
resolveAgentDeliveryPlanWithSessionRoute,
2121
resolveAgentOutboundTarget,
@@ -702,7 +702,7 @@ export async function deliverAgentCommandResult(
702702
};
703703
if (strictPreDeliveryError) {
704704
emitJsonEnvelope(deliveryStatus);
705-
throw toLintErrorObject(strictPreDeliveryError, "Non-Error thrown");
705+
throw toErrorObject(strictPreDeliveryError, "Non-Error thrown");
706706
}
707707

708708
const deliveryPayloads = projectOutboundPayloadPlanForOutbound(outboundPayloadPlan);
@@ -802,17 +802,3 @@ export async function deliverAgentCommandResult(
802802
deliveryStatus,
803803
});
804804
}
805-
806-
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
807-
if (value instanceof Error) {
808-
return value;
809-
}
810-
if (typeof value === "string") {
811-
return new Error(value);
812-
}
813-
const error = new Error(fallbackMessage, { cause: value });
814-
if ((typeof value === "object" && value !== null) || typeof value === "function") {
815-
Object.assign(error, value);
816-
}
817-
return error;
818-
}

src/agents/compaction-planning-worker.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import path from "node:path";
66
import { fileURLToPath, pathToFileURL } from "node:url";
77
import { Worker } from "node:worker_threads";
88
import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion";
9+
import { toErrorObject } from "../infra/errors.js";
910
import {
1011
buildHistoryPrunePlan,
1112
buildOversizedFallbackPlan,
@@ -60,7 +61,7 @@ function runCompactionPlanningWorker(params: {
6061
}): Promise<CompactionPlanningWorkerValue> {
6162
if (params.signal?.aborted) {
6263
return Promise.reject(
63-
toLintErrorObject(
64+
toErrorObject(
6465
params.signal.reason ?? new Error("compaction planning aborted"),
6566
"Non-Error rejection",
6667
),
@@ -105,7 +106,7 @@ function runCompactionPlanningWorker(params: {
105106
settle(
106107
() =>
107108
reject(
108-
toLintErrorObject(
109+
toErrorObject(
109110
params.signal?.reason ?? new Error("compaction planning aborted"),
110111
"Non-Error rejection",
111112
),
@@ -367,17 +368,3 @@ export const compactionPlanningWorkerTesting = {
367368
runCompactionPlanningWorker,
368369
CompactionPlanningWorkerError,
369370
};
370-
371-
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
372-
if (value instanceof Error) {
373-
return value;
374-
}
375-
if (typeof value === "string") {
376-
return new Error(value);
377-
}
378-
const error = new Error(fallbackMessage, { cause: value });
379-
if ((typeof value === "object" && value !== null) || typeof value === "function") {
380-
Object.assign(error, value);
381-
}
382-
return error;
383-
}

src/agents/harness/native-hook-relay.ts

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
resolveExpiresAtMsFromDurationMs,
2626
} from "@openclaw/normalization-core/number-coercion";
2727
import type { OpenClawConfig } from "../../config/types.openclaw.js";
28+
import { toErrorObject } from "../../infra/errors.js";
2829
import { resolveOpenClawPackageRootSync } from "../../infra/openclaw-root.js";
2930
import { privateFileStoreSync } from "../../infra/private-file-store.js";
3031
import { createSubsystemLogger } from "../../logging/subsystem.js";
@@ -1235,7 +1236,7 @@ function postNativeHookRelayBridgeRecord(params: {
12351236
const rejectOnce = (error: unknown) => {
12361237
if (!settled) {
12371238
settled = true;
1238-
reject(toLintErrorObject(error, "Non-Error rejection"));
1239+
reject(toErrorObject(error, "Non-Error rejection"));
12391240
}
12401241
};
12411242
const req = httpRequest(
@@ -2060,10 +2061,10 @@ async function waitForNativeHookRelayApprovalDecision(params: {
20602061
let onAbort: (() => void) | undefined;
20612062
const abortPromise = new Promise<never>((_, reject) => {
20622063
if (params.signal!.aborted) {
2063-
reject(toLintErrorObject(params.signal!.reason, "Non-Error rejection"));
2064+
reject(toErrorObject(params.signal!.reason, "Non-Error rejection"));
20642065
return;
20652066
}
2066-
onAbort = () => reject(toLintErrorObject(params.signal!.reason, "Non-Error rejection"));
2067+
onAbort = () => reject(toErrorObject(params.signal!.reason, "Non-Error rejection"));
20672068
params.signal!.addEventListener("abort", onAbort, { once: true });
20682069
});
20692070
try {
@@ -2380,17 +2381,3 @@ export const testing = {
23802381
},
23812382
} as const;
23822383
export { testing as __testing };
2383-
2384-
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
2385-
if (value instanceof Error) {
2386-
return value;
2387-
}
2388-
if (typeof value === "string") {
2389-
return new Error(value);
2390-
}
2391-
const error = new Error(fallbackMessage, { cause: value });
2392-
if ((typeof value === "object" && value !== null) || typeof value === "function") {
2393-
Object.assign(error, value);
2394-
}
2395-
return error;
2396-
}

src/agents/model-fallback.ts

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
} from "../config/model-input.js";
1010
import type { OpenClawConfig } from "../config/types.openclaw.js";
1111
import { emitFailoverEvent } from "../infra/diagnostic-events.js";
12-
import { formatErrorMessage } from "../infra/errors.js";
12+
import { formatErrorMessage, toErrorObject } from "../infra/errors.js";
1313
import { createSubsystemLogger } from "../logging/subsystem.js";
1414
import { normalizePluginsConfig } from "../plugins/config-state.js";
1515
import { getCurrentPluginMetadataSnapshot } from "../plugins/current-plugin-metadata-snapshot.js";
@@ -431,7 +431,7 @@ async function runFallbackAttempt<T>(params: {
431431
});
432432
if (classifiedError) {
433433
if (isTerminalAbort(params.abortSignal)) {
434-
throw toLintErrorObject(classifiedError, "Non-Error thrown");
434+
throw toErrorObject(classifiedError, "Non-Error thrown");
435435
}
436436
const preserveResultOnExhaustion =
437437
classification &&
@@ -670,7 +670,7 @@ function throwFallbackFailureSummary(params: {
670670
agentDir?: string;
671671
}): never {
672672
if (params.attempts.length <= 1 && params.lastError) {
673-
throw toLintErrorObject(params.lastError, "Non-Error thrown");
673+
throw toErrorObject(params.lastError, "Non-Error thrown");
674674
}
675675

676676
if (params.attribution?.sessionId) {
@@ -1946,17 +1946,3 @@ export async function runWithImageModelFallback<T>(params: {
19461946
});
19471947
}
19481948
export { testing as __testing };
1949-
1950-
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
1951-
if (value instanceof Error) {
1952-
return value;
1953-
}
1954-
if (typeof value === "string") {
1955-
return new Error(value);
1956-
}
1957-
const error = new Error(fallbackMessage, { cause: value });
1958-
if ((typeof value === "object" && value !== null) || typeof value === "function") {
1959-
Object.assign(error, value);
1960-
}
1961-
return error;
1962-
}

src/agents/model-provider-auth.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
88
import { Worker } from "node:worker_threads";
99
import { hashRuntimeConfigValue } from "../config/runtime-snapshot.js";
1010
import type { OpenClawConfig } from "../config/types.openclaw.js";
11+
import { toErrorObject } from "../infra/errors.js";
1112
import {
1213
listAgentIds,
1314
resolveAgentDir,
@@ -582,7 +583,7 @@ function runProviderAuthWarmWorker(params: {
582583
resolve({ agents: [] });
583584
return;
584585
}
585-
reject(toLintErrorObject(error, "Non-Error rejection"));
586+
reject(toErrorObject(error, "Non-Error rejection"));
586587
});
587588
});
588589
worker.once("exit", (code) => {
@@ -638,17 +639,3 @@ export async function warmCurrentProviderAuthStateOffMainThread(
638639
}
639640
publishProviderAuthWarmSnapshot(snapshot);
640641
}
641-
642-
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
643-
if (value instanceof Error) {
644-
return value;
645-
}
646-
if (typeof value === "string") {
647-
return new Error(value);
648-
}
649-
const error = new Error(fallbackMessage, { cause: value });
650-
if ((typeof value === "object" && value !== null) || typeof value === "function") {
651-
Object.assign(error, value);
652-
}
653-
return error;
654-
}

src/agents/provider-local-service.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
resolvePositiveTimerTimeoutMs,
1010
} from "@openclaw/normalization-core/number-coercion";
1111
import type { ModelProviderLocalServiceConfig } from "../config/types.models.js";
12+
import { toErrorObject } from "../infra/errors.js";
1213
import type { Model } from "../llm/types.js";
1314
import { createSubsystemLogger } from "../logging/subsystem.js";
1415
import {
@@ -430,7 +431,7 @@ function waitForAbort<T>(promise: Promise<T>, signal?: AbortSignal | null): Prom
430431
},
431432
(error: unknown) => {
432433
cleanup();
433-
reject(toLintErrorObject(error, "Non-Error rejection"));
434+
reject(toErrorObject(error, "Non-Error rejection"));
434435
},
435436
);
436437
});
@@ -523,17 +524,3 @@ export function hasLocalServiceProcessExited(
523524
): boolean {
524525
return child.exitCode !== null || child.signalCode !== null;
525526
}
526-
527-
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
528-
if (value instanceof Error) {
529-
return value;
530-
}
531-
if (typeof value === "string") {
532-
return new Error(value);
533-
}
534-
const error = new Error(fallbackMessage, { cause: value });
535-
if ((typeof value === "object" && value !== null) || typeof value === "function") {
536-
Object.assign(error, value);
537-
}
538-
return error;
539-
}

src/agents/sandbox/ssh.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import fs from "node:fs/promises";
88
import os from "node:os";
99
import path from "node:path";
1010
import { resolveRootPath } from "../../infra/boundary-path.js";
11+
import { toErrorObject } from "../../infra/errors.js";
1112
import { parseSshTarget } from "../../infra/ssh-tunnel.js";
1213
import { resolvePreferredOpenClawTmpDir } from "../../infra/tmp-openclaw-dir.js";
1314
import { resolveUserPath } from "../../utils.js";
@@ -743,7 +744,7 @@ export async function uploadDirectoryToSshTarget(params: {
743744
const fail = (error: unknown) => {
744745
tar.kill("SIGKILL");
745746
ssh.kill("SIGKILL");
746-
reject(toLintErrorObject(error, "Non-Error rejection"));
747+
reject(toErrorObject(error, "Non-Error rejection"));
747748
};
748749

749750
tar.on("error", fail);
@@ -846,17 +847,3 @@ async function writeSecretMaterial(
846847
await fs.chmod(pathname, 0o600);
847848
return pathname;
848849
}
849-
850-
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
851-
if (value instanceof Error) {
852-
return value;
853-
}
854-
if (typeof value === "string") {
855-
return new Error(value);
856-
}
857-
const error = new Error(fallbackMessage, { cause: value });
858-
if ((typeof value === "object" && value !== null) || typeof value === "function") {
859-
Object.assign(error, value);
860-
}
861-
return error;
862-
}

0 commit comments

Comments
 (0)