mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-17 04:01:05 +00:00
refactor: dedupe core error formatting call sites
This commit is contained in:
@@ -143,7 +143,7 @@ import {
|
||||
} from "./tool-schema-runtime.js";
|
||||
import { splitSdkTools } from "./tool-split.js";
|
||||
import type { EmbeddedPiCompactResult } from "./types.js";
|
||||
import { describeUnknownError, mapThinkingLevel } from "./utils.js";
|
||||
import { mapThinkingLevel } from "./utils.js";
|
||||
import { flushPendingToolResultsAfterIdle } from "./wait-for-idle-before-flush.js";
|
||||
|
||||
export type CompactEmbeddedPiSessionParams = {
|
||||
@@ -395,7 +395,7 @@ export async function compactEmbeddedPiSessionDirect(
|
||||
authStorage.setRuntimeApiKey(runtimeModel.provider, runtimeApiKey);
|
||||
}
|
||||
} catch (err) {
|
||||
const reason = describeUnknownError(err);
|
||||
const reason = formatErrorMessage(err);
|
||||
return fail(reason);
|
||||
}
|
||||
|
||||
@@ -1103,7 +1103,7 @@ export async function compactEmbeddedPiSessionDirect(
|
||||
};
|
||||
} catch (err) {
|
||||
const fallbackThinking = pickFallbackThinkingLevel({
|
||||
message: describeUnknownError(err),
|
||||
message: formatErrorMessage(err),
|
||||
attempted: attemptedThinking,
|
||||
});
|
||||
if (fallbackThinking) {
|
||||
@@ -1149,7 +1149,7 @@ export async function compactEmbeddedPiSessionDirect(
|
||||
}
|
||||
} catch (err) {
|
||||
const reason = resolveCompactionFailureReason({
|
||||
reason: describeUnknownError(err),
|
||||
reason: formatErrorMessage(err),
|
||||
safeguardCancelReason: consumeCompactionSafeguardCancelReason(compactionSessionManager),
|
||||
});
|
||||
return fail(reason);
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
} from "../../context-engine/index.js";
|
||||
import { emitAgentPlanEvent } from "../../infra/agent-events.js";
|
||||
import { sleepWithAbort } from "../../infra/backoff.js";
|
||||
import { formatErrorMessage } from "../../infra/errors.js";
|
||||
import { getGlobalHookRunner } from "../../plugins/hook-runner-global.js";
|
||||
import { enqueueCommandInLane } from "../../process/command-queue.js";
|
||||
import { sanitizeForLog } from "../../terminal/ansi.js";
|
||||
@@ -101,7 +102,6 @@ import {
|
||||
} from "./tool-result-truncation.js";
|
||||
import type { EmbeddedPiAgentMeta, EmbeddedPiRunResult } from "./types.js";
|
||||
import { createUsageAccumulator, mergeUsageIntoAccumulator } from "./usage-accumulator.js";
|
||||
import { describeUnknownError } from "./utils.js";
|
||||
|
||||
type ApiKeyInfo = ResolvedProviderAuth;
|
||||
|
||||
@@ -139,7 +139,7 @@ function backfillSessionKey(params: {
|
||||
return resolved.sessionKey?.trim() || undefined;
|
||||
} catch (err) {
|
||||
log.warn(
|
||||
`[backfillSessionKey] Failed to resolve sessionKey for sessionId=${redactRunIdentifier(sanitizeForLog(params.sessionId))}: ${describeUnknownError(err)}`,
|
||||
`[backfillSessionKey] Failed to resolve sessionKey for sessionId=${redactRunIdentifier(sanitizeForLog(params.sessionId))}: ${formatErrorMessage(err)}`,
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
@@ -850,7 +850,7 @@ export async function runEmbeddedPiAgent(
|
||||
const contextOverflowError = !aborted
|
||||
? (() => {
|
||||
if (promptError) {
|
||||
const errorText = describeUnknownError(promptError);
|
||||
const errorText = formatErrorMessage(promptError);
|
||||
if (isLikelyContextOverflowError(errorText)) {
|
||||
return { text: errorText, source: "promptError" as const };
|
||||
}
|
||||
@@ -1092,7 +1092,7 @@ export async function runEmbeddedPiAgent(
|
||||
const promptErrorDetails = normalizedPromptFailover
|
||||
? describeFailoverError(normalizedPromptFailover)
|
||||
: describeFailoverError(promptError);
|
||||
const errorText = promptErrorDetails.message || describeUnknownError(promptError);
|
||||
const errorText = promptErrorDetails.message || formatErrorMessage(promptError);
|
||||
if (await maybeRefreshRuntimeAuthForAuthError(errorText, runtimeAuthRetry)) {
|
||||
authRetryPending = true;
|
||||
continue;
|
||||
@@ -1584,7 +1584,7 @@ export async function runEmbeddedPiAgent(
|
||||
if (params.cleanupBundleMcpOnRunEnd === true) {
|
||||
await disposeSessionMcpRuntime(params.sessionId).catch((error) => {
|
||||
log.warn(
|
||||
`bundle-mcp cleanup failed after run for ${params.sessionId}: ${describeUnknownError(error)}`,
|
||||
`bundle-mcp cleanup failed after run for ${params.sessionId}: ${formatErrorMessage(error)}`,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
import { filterHeartbeatPairs } from "../../../auto-reply/heartbeat-filter.js";
|
||||
import { resolveHeartbeatPrompt } from "../../../auto-reply/heartbeat.js";
|
||||
import { resolveChannelCapabilities } from "../../../config/channel-capabilities.js";
|
||||
import { formatErrorMessage } from "../../../infra/errors.js";
|
||||
import { resolveHeartbeatSummaryForAgent } from "../../../infra/heartbeat-summary.js";
|
||||
import { getMachineDisplayName } from "../../../infra/machine-name.js";
|
||||
import {
|
||||
@@ -151,7 +152,7 @@ import {
|
||||
normalizeProviderToolSchemas,
|
||||
} from "../tool-schema-runtime.js";
|
||||
import { splitSdkTools } from "../tool-split.js";
|
||||
import { describeUnknownError, mapThinkingLevel } from "../utils.js";
|
||||
import { mapThinkingLevel } from "../utils.js";
|
||||
import { flushPendingToolResultsAfterIdle } from "../wait-for-idle-before-flush.js";
|
||||
import {
|
||||
assembleAttemptContextEngine,
|
||||
@@ -1992,7 +1993,7 @@ export async function runEmbeddedAttempt(
|
||||
provider: params.provider,
|
||||
model: params.modelId,
|
||||
api: params.model.api,
|
||||
error: describeUnknownError(promptError),
|
||||
error: formatErrorMessage(promptError),
|
||||
});
|
||||
} catch (entryErr) {
|
||||
log.warn(`failed to persist prompt error entry: ${String(entryErr)}`);
|
||||
@@ -2071,7 +2072,7 @@ export async function runEmbeddedAttempt(
|
||||
{
|
||||
messages: messagesSnapshot,
|
||||
success: !aborted && !promptError,
|
||||
error: promptError ? describeUnknownError(promptError) : undefined,
|
||||
error: promptError ? formatErrorMessage(promptError) : undefined,
|
||||
durationMs: Date.now() - promptStartedAt,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Api, Model } from "@mariozechner/pi-ai";
|
||||
import type { ThinkLevel } from "../../../auto-reply/thinking.js";
|
||||
import { formatErrorMessage } from "../../../infra/errors.js";
|
||||
import { prepareProviderRuntimeAuth } from "../../../plugins/provider-runtime.js";
|
||||
import {
|
||||
type AuthProfileStore,
|
||||
@@ -19,7 +20,6 @@ import {
|
||||
sanitizeRuntimeProviderRequestOverrides,
|
||||
} from "../../provider-request-config.js";
|
||||
import { clampRuntimeAuthRefreshDelayMs } from "../../runtime-auth-refresh.js";
|
||||
import { describeUnknownError } from "../utils.js";
|
||||
import {
|
||||
RUNTIME_AUTH_REFRESH_MARGIN_MS,
|
||||
RUNTIME_AUTH_REFRESH_MIN_DELAY_MS,
|
||||
@@ -186,7 +186,7 @@ export function createEmbeddedRunAuthController(params: {
|
||||
.catch((err) => {
|
||||
const runtimeModel = params.getRuntimeModel();
|
||||
params.log.warn(
|
||||
`Runtime auth refresh failed for ${runtimeModel.provider}: ${describeUnknownError(err)}`,
|
||||
`Runtime auth refresh failed for ${runtimeModel.provider}: ${formatErrorMessage(err)}`,
|
||||
);
|
||||
throw err;
|
||||
})
|
||||
@@ -289,7 +289,7 @@ export function createEmbeddedRunAuthController(params: {
|
||||
const fallbackMessage = `No available auth profile for ${provider} (all in cooldown or unavailable).`;
|
||||
const message =
|
||||
failoverParams.message?.trim() ||
|
||||
(failoverParams.error ? describeUnknownError(failoverParams.error).trim() : "") ||
|
||||
(failoverParams.error ? formatErrorMessage(failoverParams.error).trim() : "") ||
|
||||
fallbackMessage;
|
||||
const reason = resolveAuthProfileFailoverReason({
|
||||
allInCooldown: failoverParams.allInCooldown,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { ThinkingLevel } from "@mariozechner/pi-agent-core";
|
||||
import type { ReasoningLevel, ThinkLevel } from "../../auto-reply/thinking.js";
|
||||
import { formatErrorMessage } from "../../infra/errors.js";
|
||||
|
||||
export function mapThinkingLevel(level?: ThinkLevel): ThinkingLevel {
|
||||
// pi-agent-core supports "xhigh"; OpenClaw enables it for specific models.
|
||||
@@ -17,8 +16,4 @@ export function mapThinkingLevel(level?: ThinkLevel): ThinkingLevel {
|
||||
return level;
|
||||
}
|
||||
|
||||
export function describeUnknownError(error: unknown): string {
|
||||
return formatErrorMessage(error);
|
||||
}
|
||||
|
||||
export type { ReasoningLevel, ThinkLevel };
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveSecretInputRef } from "../config/types.secrets.js";
|
||||
import { callGateway } from "../gateway/call.js";
|
||||
import { validateSecretsResolveResult } from "../gateway/protocol/index.js";
|
||||
import { formatErrorMessage } from "../infra/errors.js";
|
||||
import { resolveManifestContractOwnerPluginId } from "../plugins/manifest-registry.js";
|
||||
import {
|
||||
analyzeCommandSecretAssignmentsFromSnapshot,
|
||||
@@ -13,7 +14,6 @@ import { collectConfigAssignments } from "../secrets/runtime-config-collectors.j
|
||||
import { createResolverContext } from "../secrets/runtime-shared.js";
|
||||
import { resolveRuntimeWebTools } from "../secrets/runtime-web-tools.js";
|
||||
import { assertExpectedResolvedSecretValue } from "../secrets/secret-value.js";
|
||||
import { describeUnknownError } from "../secrets/shared.js";
|
||||
import {
|
||||
discoverConfigSecretTargetsByIds,
|
||||
type DiscoveredConfigSecretTarget,
|
||||
@@ -398,7 +398,7 @@ function collectInactiveSurfacePathsFromDiagnostics(diagnostics: string[]): Set<
|
||||
}
|
||||
|
||||
function isUnsupportedSecretsResolveError(err: unknown): boolean {
|
||||
const message = describeUnknownError(err).toLowerCase();
|
||||
const message = formatErrorMessage(err).toLowerCase();
|
||||
if (!message.includes("secrets.resolve")) {
|
||||
return false;
|
||||
}
|
||||
@@ -460,7 +460,7 @@ async function resolveCommandSecretRefsLocally(params: {
|
||||
throw error;
|
||||
}
|
||||
localResolutionDiagnostics.push(
|
||||
`${params.commandName}: failed to resolve web tool secrets locally (${describeUnknownError(error)}).`,
|
||||
`${params.commandName}: failed to resolve web tool secrets locally (${formatErrorMessage(error)}).`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -650,7 +650,7 @@ async function resolveTargetSecretLocally(params: {
|
||||
} catch (error) {
|
||||
if (!enforcesResolvedSecrets(params.mode)) {
|
||||
params.localResolutionDiagnostics.push(
|
||||
`${params.commandName}: failed to resolve ${params.target.path} locally (${describeUnknownError(error)}).`,
|
||||
`${params.commandName}: failed to resolve ${params.target.path} locally (${formatErrorMessage(error)}).`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -725,7 +725,7 @@ export async function resolveCommandSecretRefsViaGateway(params: {
|
||||
resolvedConfig: fallback.resolvedConfig,
|
||||
diagnostics: dedupeDiagnostics([
|
||||
...fallback.diagnostics,
|
||||
`${params.commandName}: gateway secrets.resolve unavailable (${describeUnknownError(err)}); ${fallbackMessage}`,
|
||||
`${params.commandName}: gateway secrets.resolve unavailable (${formatErrorMessage(err)}); ${fallbackMessage}`,
|
||||
]),
|
||||
targetStatesByPath: fallback.targetStatesByPath,
|
||||
hadUnresolvedTargets: fallback.hadUnresolvedTargets,
|
||||
@@ -735,12 +735,12 @@ export async function resolveCommandSecretRefsViaGateway(params: {
|
||||
}
|
||||
if (isUnsupportedSecretsResolveError(err)) {
|
||||
throw new Error(
|
||||
`${params.commandName}: active gateway does not support secrets.resolve (${describeUnknownError(err)}). Update the gateway or run without SecretRefs.`,
|
||||
`${params.commandName}: active gateway does not support secrets.resolve (${formatErrorMessage(err)}). Update the gateway or run without SecretRefs.`,
|
||||
{ cause: err },
|
||||
);
|
||||
}
|
||||
throw new Error(
|
||||
`${params.commandName}: failed to resolve secrets from the active gateway snapshot (${describeUnknownError(err)}). Start the gateway and retry.`,
|
||||
`${params.commandName}: failed to resolve secrets from the active gateway snapshot (${formatErrorMessage(err)}). Start the gateway and retry.`,
|
||||
{ cause: err },
|
||||
);
|
||||
}
|
||||
@@ -757,7 +757,7 @@ export async function resolveCommandSecretRefsViaGateway(params: {
|
||||
} catch (err) {
|
||||
const path = pathSegments.join(".");
|
||||
throw new Error(
|
||||
`${params.commandName}: failed to apply resolved secret assignment at ${path} (${describeUnknownError(err)}).`,
|
||||
`${params.commandName}: failed to apply resolved secret assignment at ${path} (${formatErrorMessage(err)}).`,
|
||||
{ cause: err },
|
||||
);
|
||||
}
|
||||
@@ -837,7 +837,7 @@ export async function resolveCommandSecretRefsViaGateway(params: {
|
||||
scrubUnresolvedAssignments(resolvedConfig, analyzed.unresolved);
|
||||
diagnostics = dedupeDiagnostics([
|
||||
...diagnostics,
|
||||
`${params.commandName}: local fallback after incomplete gateway snapshot failed (${describeUnknownError(error)}).`,
|
||||
`${params.commandName}: local fallback after incomplete gateway snapshot failed (${formatErrorMessage(error)}).`,
|
||||
...buildUnresolvedDiagnostics(params.commandName, analyzed.unresolved, mode),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import fs from "node:fs/promises";
|
||||
import type { Command } from "commander";
|
||||
import JSON5 from "json5";
|
||||
import { readBestEffortConfig, type OpenClawConfig } from "../config/config.js";
|
||||
import { formatErrorMessage } from "../infra/errors.js";
|
||||
import {
|
||||
collectExecPolicyScopeSnapshots,
|
||||
type ExecPolicyScopeSnapshot,
|
||||
@@ -17,7 +18,6 @@ import { defaultRuntime } from "../runtime.js";
|
||||
import { formatDocsLink } from "../terminal/links.js";
|
||||
import { getTerminalTableWidth, renderTable } from "../terminal/table.js";
|
||||
import { isRich, theme } from "../terminal/theme.js";
|
||||
import { describeUnknownError } from "./gateway-cli/shared.js";
|
||||
import { callGatewayFromCli } from "./gateway-rpc.js";
|
||||
import { nodesCallOpts, resolveNodeId } from "./nodes-cli/rpc.js";
|
||||
import type { NodesRpcOpts } from "./nodes-cli/types.js";
|
||||
@@ -157,7 +157,7 @@ async function saveSnapshotTargeted(params: {
|
||||
}
|
||||
|
||||
function formatCliError(err: unknown): string {
|
||||
const msg = describeUnknownError(err);
|
||||
const msg = formatErrorMessage(err);
|
||||
return msg.includes("\n") ? msg.split("\n")[0] : msg;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ import { withProgress } from "../progress.js";
|
||||
import { ensureDevGatewayConfig } from "./dev.js";
|
||||
import { runGatewayLoop } from "./run-loop.js";
|
||||
import {
|
||||
describeUnknownError,
|
||||
extractGatewayMiskeys,
|
||||
maybeExplainGatewayServiceStop,
|
||||
parsePort,
|
||||
@@ -559,7 +558,7 @@ async function runGatewayCommand(opts: GatewayRunOpts) {
|
||||
}
|
||||
} catch (err) {
|
||||
if (isGatewayLockError(err)) {
|
||||
const errMessage = describeUnknownError(err);
|
||||
const errMessage = formatErrorMessage(err);
|
||||
defaultRuntime.error(
|
||||
`Gateway failed to start: ${errMessage}\nIf the gateway is supervised, stop it with: ${formatCliCommand("openclaw gateway stop")}`,
|
||||
);
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
resolveGatewayWindowsTaskName,
|
||||
} from "../../daemon/constants.js";
|
||||
import { resolveGatewayService } from "../../daemon/service.js";
|
||||
import { formatErrorMessage } from "../../infra/errors.js";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { formatCliCommand } from "../command-format.js";
|
||||
import { parsePort } from "../shared/parse-port.js";
|
||||
@@ -21,10 +20,6 @@ export const toOptionString = (value: unknown): string | undefined => {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export function describeUnknownError(err: unknown): string {
|
||||
return formatErrorMessage(err);
|
||||
}
|
||||
|
||||
export function extractGatewayMiskeys(parsed: unknown): {
|
||||
hasGatewayToken: boolean;
|
||||
hasRemoteToken: boolean;
|
||||
|
||||
@@ -9,6 +9,7 @@ import { normalizeProviderId } from "../agents/model-selection.js";
|
||||
import { resolveStateDir, type OpenClawConfig } from "../config/config.js";
|
||||
import { coerceSecretRef } from "../config/types.secrets.js";
|
||||
import { resolveSecretInputRef, type SecretRef } from "../config/types.secrets.js";
|
||||
import { formatErrorMessage } from "../infra/errors.js";
|
||||
import { resolveConfigDir, resolveUserPath } from "../utils.js";
|
||||
import { runTasksWithConcurrency } from "../utils/run-with-concurrency.js";
|
||||
import { iterateAuthProfileCredentials } from "./auth-profiles-scan.js";
|
||||
@@ -27,7 +28,6 @@ import {
|
||||
isExpectedResolvedSecretValue,
|
||||
} from "./secret-value.js";
|
||||
import { isNonEmptyString, isRecord } from "./shared.js";
|
||||
import { describeUnknownError } from "./shared.js";
|
||||
import {
|
||||
listAgentModelsJsonPaths,
|
||||
listAuthProfileStorePaths,
|
||||
@@ -568,7 +568,7 @@ async function collectUnresolvedRefFindings(params: {
|
||||
severity: "error",
|
||||
file: assignment.file,
|
||||
jsonPath: assignment.path,
|
||||
message: `Failed to resolve ${assignment.ref.source}:${assignment.ref.provider}:${assignment.ref.id} (${describeUnknownError(resolveErr)}).`,
|
||||
message: `Failed to resolve ${assignment.ref.source}:${assignment.ref.provider}:${assignment.ref.id} (${formatErrorMessage(resolveErr)}).`,
|
||||
provider: assignment.provider,
|
||||
});
|
||||
continue;
|
||||
|
||||
@@ -9,6 +9,7 @@ import type {
|
||||
SecretRef,
|
||||
SecretRefSource,
|
||||
} from "../config/types.secrets.js";
|
||||
import { formatErrorMessage } from "../infra/errors.js";
|
||||
import { inspectPathPermissions, safeStat } from "../security/audit-fs.js";
|
||||
import { isPathInside } from "../security/scan-paths.js";
|
||||
import { resolveUserPath } from "../utils.js";
|
||||
@@ -21,12 +22,7 @@ import {
|
||||
resolveDefaultSecretProviderAlias,
|
||||
secretRefKey,
|
||||
} from "./ref-contract.js";
|
||||
import {
|
||||
describeUnknownError,
|
||||
isNonEmptyString,
|
||||
isRecord,
|
||||
normalizePositiveInt,
|
||||
} from "./shared.js";
|
||||
import { isNonEmptyString, isRecord, normalizePositiveInt } from "./shared.js";
|
||||
|
||||
const DEFAULT_PROVIDER_CONCURRENCY = 4;
|
||||
const DEFAULT_MAX_REFS_PER_PROVIDER = 512;
|
||||
@@ -140,7 +136,7 @@ function throwUnknownProviderResolutionError(params: {
|
||||
throw providerResolutionError({
|
||||
source: params.source,
|
||||
provider: params.provider,
|
||||
message: describeUnknownError(params.err),
|
||||
message: formatErrorMessage(params.err),
|
||||
cause: params.err,
|
||||
});
|
||||
}
|
||||
@@ -419,7 +415,7 @@ async function resolveFileRefs(params: {
|
||||
source: "file",
|
||||
provider: params.providerName,
|
||||
refId: ref.id,
|
||||
message: describeUnknownError(err),
|
||||
message: formatErrorMessage(err),
|
||||
cause: err,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { formatErrorMessage } from "../infra/errors.js";
|
||||
export { isRecord } from "../utils.js";
|
||||
|
||||
export function isNonEmptyString(value: unknown): value is string {
|
||||
@@ -60,7 +59,3 @@ export function writeTextFileAtomic(pathname: string, value: string, mode = 0o60
|
||||
fs.chmodSync(tempPath, mode);
|
||||
fs.renameSync(tempPath, pathname);
|
||||
}
|
||||
|
||||
export function describeUnknownError(err: unknown): string {
|
||||
return formatErrorMessage(err);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user