mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
chore(lint): enable stricter error rules
This commit is contained in:
@@ -82,7 +82,10 @@
|
||||
"typescript/no-meaningless-void-operator": "error",
|
||||
"typescript/no-misused-promises": "error",
|
||||
"typescript/no-inferrable-types": "error",
|
||||
"typescript/only-throw-error": "error",
|
||||
"typescript/no-non-null-asserted-nullish-coalescing": "error",
|
||||
"typescript/prefer-promise-reject-errors": "error",
|
||||
"typescript/restrict-plus-operands": "error",
|
||||
"typescript/no-unnecessary-qualifier": "error",
|
||||
"typescript/no-unnecessary-type-assertion": "error",
|
||||
"typescript/no-unnecessary-type-arguments": "error",
|
||||
@@ -109,6 +112,8 @@
|
||||
"typescript/require-array-sort-compare": "error",
|
||||
"typescript/restrict-template-expressions": "error",
|
||||
"typescript/triple-slash-reference": "error",
|
||||
"typescript/unbound-method": "error",
|
||||
"typescript/use-unknown-in-catch-callback-variable": "error",
|
||||
"unicorn/consistent-date-clone": "error",
|
||||
"unicorn/consistent-empty-array-spread": "error",
|
||||
"unicorn/consistent-function-scoping": "off",
|
||||
@@ -128,6 +133,7 @@
|
||||
"unicorn/no-unnecessary-slice-end": "error",
|
||||
"unicorn/no-useless-error-capture-stack-trace": "error",
|
||||
"unicorn/no-useless-promise-resolve-reject": "error",
|
||||
"unicorn/no-useless-switch-case": "error",
|
||||
"unicorn/no-zero-fractions": "error",
|
||||
"unicorn/prefer-date-now": "error",
|
||||
"unicorn/prefer-dom-node-text-content": "error",
|
||||
|
||||
@@ -68,7 +68,7 @@ class LegacyRunTurnEventQueue {
|
||||
return item;
|
||||
}
|
||||
if (this.error) {
|
||||
throw this.error;
|
||||
throw toLintErrorObject(this.error, "Non-Error thrown");
|
||||
}
|
||||
if (this.closed) {
|
||||
return null;
|
||||
@@ -178,3 +178,17 @@ export function lazyStartRuntimeTurn(
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ describe("AcpxRuntime fresh reset wrapper", () => {
|
||||
})
|
||||
.then(
|
||||
() => ({ status: "resolved" as const }),
|
||||
(error) => ({ status: "rejected" as const, error }),
|
||||
(error: unknown) => ({ status: "rejected" as const, error }),
|
||||
);
|
||||
|
||||
expect(outcome.status).toBe("rejected");
|
||||
@@ -298,7 +298,12 @@ describe("AcpxRuntime fresh reset wrapper", () => {
|
||||
code: "ACP_SESSION_INIT_FAILED",
|
||||
message: expect.stringContaining("deployment missing"),
|
||||
});
|
||||
expect(outcome.error.message).not.toContain("sk-testsecret1234567890");
|
||||
const error = outcome.error;
|
||||
expect(error).toBeInstanceOf(AcpRuntimeError);
|
||||
if (!(error instanceof AcpRuntimeError)) {
|
||||
throw new Error("expected AcpRuntimeError");
|
||||
}
|
||||
expect(error.message).not.toContain("sk-testsecret1234567890");
|
||||
});
|
||||
|
||||
it("adds Codex wrapper stderr tail to generic first-turn failures", async () => {
|
||||
|
||||
@@ -218,13 +218,21 @@ describe("active-memory plugin", () => {
|
||||
};
|
||||
const waitForAbort = async (abortSignal?: AbortSignal): Promise<never> => {
|
||||
if (abortSignal?.aborted) {
|
||||
throw (abortSignal.reason as unknown) ?? new Error("Operation aborted");
|
||||
throw toLintErrorObject(
|
||||
(abortSignal.reason as unknown) ?? new Error("Operation aborted"),
|
||||
"Non-Error thrown",
|
||||
);
|
||||
}
|
||||
return await new Promise<never>((_resolve, reject) => {
|
||||
abortSignal?.addEventListener(
|
||||
"abort",
|
||||
() => {
|
||||
reject((abortSignal.reason as unknown) ?? new Error("Operation aborted"));
|
||||
reject(
|
||||
toLintErrorObject(
|
||||
(abortSignal.reason as unknown) ?? new Error("Operation aborted"),
|
||||
"Non-Error rejection",
|
||||
),
|
||||
);
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
@@ -4350,3 +4358,17 @@ describe("active-memory plugin", () => {
|
||||
expect(config.circuitBreakerCooldownMs).toBe(5000);
|
||||
});
|
||||
});
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1011,7 +1011,6 @@ function buildPromptStyleLines(style: ActiveMemoryPromptStyle): string[] {
|
||||
"If relevant memory is mostly a stable user preference or recurring habit, lean toward returning it.",
|
||||
"If the strongest match is only a one-off historical fact and not a recurring preference or habit, prefer NONE unless the latest user message clearly asks for that fact.",
|
||||
];
|
||||
case "balanced":
|
||||
default:
|
||||
return [
|
||||
"Treat the latest user message as the primary query.",
|
||||
@@ -1982,7 +1981,7 @@ async function waitForSubagentPartialTimeoutData(
|
||||
(await Promise.race([
|
||||
subagentPromise.then(
|
||||
() => undefined,
|
||||
(error) => readPartialTimeoutData(error),
|
||||
(error: unknown) => readPartialTimeoutData(error),
|
||||
),
|
||||
timeoutPromise,
|
||||
])) ?? {}
|
||||
|
||||
@@ -571,7 +571,7 @@ export async function startGatewayBonjourAdvertiser(
|
||||
.then(() => {
|
||||
logger.info(`bonjour: advertised ${serviceSummary(label, svc)}`);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch((err: unknown) => {
|
||||
handleAdvertiseFailure(label, svc, err, "failed");
|
||||
});
|
||||
} catch (err) {
|
||||
@@ -747,7 +747,7 @@ export async function startGatewayBonjourAdvertiser(
|
||||
)})`,
|
||||
);
|
||||
try {
|
||||
void svc.advertise().catch((err) => {
|
||||
void svc.advertise().catch((err: unknown) => {
|
||||
logger.warn(
|
||||
`bonjour: watchdog re-advertise failed (${serviceSummary(label, svc)}): ${formatBonjourError(err)}`,
|
||||
);
|
||||
|
||||
@@ -416,7 +416,8 @@ describe("cdp.helpers internal", () => {
|
||||
await expect(
|
||||
withCdpSocket(server.url, async (send) => {
|
||||
await send("Test.ok");
|
||||
const rejectRawString = () => Promise.reject("raw-string-from-callback");
|
||||
const rejectRawString = () =>
|
||||
Promise.reject(toLintErrorObject("raw-string-from-callback", "Non-Error rejection"));
|
||||
return rejectRawString();
|
||||
}),
|
||||
).rejects.toThrow(/raw-string-from-callback/);
|
||||
@@ -572,3 +573,17 @@ describe("openCdpWebSocket option handling", () => {
|
||||
ws.close();
|
||||
});
|
||||
});
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ function extractJsonMessage(result: ChromeMcpToolResult): unknown {
|
||||
}
|
||||
}
|
||||
if (lastError) {
|
||||
throw lastError;
|
||||
throw toLintErrorObject(lastError, "Non-Error thrown");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -629,7 +629,7 @@ async function closeChromeMcpClientAndProcess(params: {
|
||||
return;
|
||||
}
|
||||
await params.client.close().catch(() => {});
|
||||
await terminateChromeMcpProcessTree(rootPid, descendantPids).catch((err) => {
|
||||
await terminateChromeMcpProcessTree(rootPid, descendantPids).catch((err: unknown) => {
|
||||
log.trace(
|
||||
`Unable to fully terminate Chrome MCP subprocess tree for pid ${rootPid}: ${err instanceof Error ? err.message : String(err)}`,
|
||||
);
|
||||
@@ -761,7 +761,8 @@ async function waitForChromeMcpReady(
|
||||
if (signal) {
|
||||
racers.push(
|
||||
new Promise<never>((_, reject) => {
|
||||
abortListener = () => reject(signal.reason ?? new Error("aborted"));
|
||||
abortListener = () =>
|
||||
reject(toLintErrorObject(signal.reason ?? new Error("aborted"), "Non-Error rejection"));
|
||||
signal.addEventListener("abort", abortListener, { once: true });
|
||||
}),
|
||||
);
|
||||
@@ -793,7 +794,8 @@ async function waitForChromeMcpPendingSession(
|
||||
return await Promise.race([
|
||||
pending,
|
||||
new Promise<never>((_, reject) => {
|
||||
abortListener = () => reject(signal.reason ?? new Error("aborted"));
|
||||
abortListener = () =>
|
||||
reject(toLintErrorObject(signal.reason ?? new Error("aborted"), "Non-Error rejection"));
|
||||
signal.addEventListener("abort", abortListener, { once: true });
|
||||
}),
|
||||
]);
|
||||
@@ -1022,7 +1024,8 @@ async function callTool(
|
||||
if (signal) {
|
||||
racers.push(
|
||||
new Promise<never>((_, reject) => {
|
||||
abortListener = () => reject(signal.reason ?? new Error("aborted"));
|
||||
abortListener = () =>
|
||||
reject(toLintErrorObject(signal.reason ?? new Error("aborted"), "Non-Error rejection"));
|
||||
signal.addEventListener("abort", abortListener, { once: true });
|
||||
}),
|
||||
);
|
||||
@@ -1540,3 +1543,17 @@ export async function resetChromeMcpSessionsForTest(): Promise<void> {
|
||||
await stopAllChromeMcpSessions();
|
||||
chromeMcpProcessCleanupDepsForTest = null;
|
||||
}
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -315,9 +315,17 @@ export async function fetchBrowserJson<T>(
|
||||
|
||||
let abortListener: (() => void) | undefined;
|
||||
const abortPromise: Promise<never> = abortCtrl.signal.aborted
|
||||
? Promise.reject(abortCtrl.signal.reason ?? new Error("aborted"))
|
||||
? Promise.reject(
|
||||
toLintErrorObject(abortCtrl.signal.reason ?? new Error("aborted"), "Non-Error rejection"),
|
||||
)
|
||||
: new Promise((_, reject) => {
|
||||
abortListener = () => reject(abortCtrl.signal.reason ?? new Error("aborted"));
|
||||
abortListener = () =>
|
||||
reject(
|
||||
toLintErrorObject(
|
||||
abortCtrl.signal.reason ?? new Error("aborted"),
|
||||
"Non-Error rejection",
|
||||
),
|
||||
);
|
||||
abortCtrl.signal.addEventListener("abort", abortListener, { once: true });
|
||||
});
|
||||
|
||||
@@ -382,3 +390,17 @@ export const testApi = {
|
||||
withLoopbackBrowserAuth: withLoopbackBrowserAuthImpl,
|
||||
};
|
||||
export { testApi as __test };
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1359,12 +1359,12 @@ export async function gotoPageWithNavigationGuard(
|
||||
try {
|
||||
const response = await opts.page.goto(opts.url, { timeout: opts.timeoutMs });
|
||||
if (blockedError) {
|
||||
throw blockedError;
|
||||
throw toLintErrorObject(blockedError, "Non-Error thrown");
|
||||
}
|
||||
return response;
|
||||
} catch (err) {
|
||||
if (blockedError) {
|
||||
throw blockedError;
|
||||
throw toLintErrorObject(blockedError, "Non-Error thrown");
|
||||
}
|
||||
throw err;
|
||||
} finally {
|
||||
@@ -1813,3 +1813,17 @@ export async function focusPageByTargetIdViaPlaywright(opts: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ async function assertObservedDelayedNavigations(opts: {
|
||||
});
|
||||
}
|
||||
if (subframeError) {
|
||||
throw subframeError;
|
||||
throw toLintErrorObject(subframeError, "Non-Error thrown");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ function scheduleDelayedInteractionNavigationGuard(opts: {
|
||||
const settle = (err?: unknown) => {
|
||||
cleanup();
|
||||
if (err) {
|
||||
reject(err);
|
||||
reject(toLintErrorObject(err, "Non-Error rejection"));
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
@@ -428,11 +428,11 @@ async function assertInteractionNavigationCompletedSafely<T>(opts: {
|
||||
}
|
||||
|
||||
if (subframeError) {
|
||||
throw subframeError;
|
||||
throw toLintErrorObject(subframeError, "Non-Error thrown");
|
||||
}
|
||||
|
||||
if (actionError) {
|
||||
throw actionError;
|
||||
throw toLintErrorObject(actionError, "Non-Error thrown");
|
||||
}
|
||||
return result as T;
|
||||
}
|
||||
@@ -478,12 +478,14 @@ function createAbortPromiseWithListener(
|
||||
const abortPromise: Promise<never> = signal.aborted
|
||||
? (() => {
|
||||
onAbort?.(signal.reason);
|
||||
return Promise.reject(signal.reason ?? new Error("aborted"));
|
||||
return Promise.reject(
|
||||
toLintErrorObject(signal.reason ?? new Error("aborted"), "Non-Error rejection"),
|
||||
);
|
||||
})()
|
||||
: new Promise((_, reject) => {
|
||||
abortListener = () => {
|
||||
onAbort?.(signal.reason);
|
||||
reject(signal.reason ?? new Error("aborted"));
|
||||
reject(toLintErrorObject(signal.reason ?? new Error("aborted"), "Non-Error rejection"));
|
||||
};
|
||||
signal.addEventListener("abort", abortListener, { once: true });
|
||||
});
|
||||
@@ -1712,3 +1714,17 @@ export async function batchViaPlaywright(opts: {
|
||||
}
|
||||
return { results };
|
||||
}
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ async function runExistingSessionActionWithNavigationGuard<T>(params: {
|
||||
}
|
||||
|
||||
if (actionError) {
|
||||
throw actionError;
|
||||
throw toLintErrorObject(actionError, "Non-Error thrown");
|
||||
}
|
||||
|
||||
return result as T;
|
||||
@@ -809,3 +809,17 @@ export function registerBrowserAgentActRoutes(
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -701,7 +701,7 @@ export function registerBrowserAgentSnapshotRoutes(
|
||||
const pw = await getPwAiModule();
|
||||
const snap = plan.wantsRoleSnapshot
|
||||
? pw
|
||||
? await pw.snapshotRoleViaPlaywright(roleSnapshotArgs).catch(async (err) => {
|
||||
? await pw.snapshotRoleViaPlaywright(roleSnapshotArgs).catch(async (err: unknown) => {
|
||||
const fallback = await cdpRoleSnapshot();
|
||||
if (fallback) {
|
||||
return fallback;
|
||||
|
||||
@@ -20,10 +20,21 @@ describe("browser route dispatcher (abort)", () => {
|
||||
const signal = req.signal;
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
if (signal?.aborted) {
|
||||
reject(signal.reason ?? new Error("aborted"));
|
||||
reject(
|
||||
toLintErrorObject(
|
||||
signal.reason ?? new Error("aborted"),
|
||||
"Non-Error rejection",
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
const onAbort = () => reject(signal?.reason ?? new Error("aborted"));
|
||||
const onAbort = () =>
|
||||
reject(
|
||||
toLintErrorObject(
|
||||
signal?.reason ?? new Error("aborted"),
|
||||
"Non-Error rejection",
|
||||
),
|
||||
);
|
||||
signal?.addEventListener("abort", onAbort, { once: true });
|
||||
queueMicrotask(() => {
|
||||
signal?.removeEventListener("abort", onAbort);
|
||||
@@ -81,3 +92,17 @@ describe("browser route dispatcher (abort)", () => {
|
||||
expect(body.error).toBe("invalid path parameter encoding: id");
|
||||
});
|
||||
});
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ export async function normalizeBrowserScreenshot(
|
||||
}
|
||||
|
||||
if (processorUnavailableError) {
|
||||
throw processorUnavailableError;
|
||||
throw toLintErrorObject(processorUnavailableError, "Non-Error thrown");
|
||||
}
|
||||
|
||||
const best = smallest?.buffer ?? buffer;
|
||||
@@ -74,3 +74,17 @@ export async function normalizeBrowserScreenshot(
|
||||
`Browser screenshot could not be reduced below ${(maxBytes / (1024 * 1024)).toFixed(0)}MB (got ${(best.byteLength / (1024 * 1024)).toFixed(2)}MB)`,
|
||||
);
|
||||
}
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -377,7 +377,7 @@ export function createProfileTabOps({
|
||||
method: "PUT",
|
||||
},
|
||||
getCdpControlPolicy(),
|
||||
).catch(async (err) => {
|
||||
).catch(async (err: unknown) => {
|
||||
if (String(err).includes("HTTP 405")) {
|
||||
return await fetchJson<CdpTarget>(
|
||||
endpoint,
|
||||
|
||||
@@ -57,7 +57,10 @@ vi.mock("../sdk-node-runtime.js", () => ({
|
||||
new Promise<never>((_, reject) => {
|
||||
abortCtrl.signal.addEventListener(
|
||||
"abort",
|
||||
() => reject(abortCtrl.signal.reason ?? timeoutError),
|
||||
() =>
|
||||
reject(
|
||||
toLintErrorObject(abortCtrl.signal.reason ?? timeoutError, "Non-Error rejection"),
|
||||
),
|
||||
{ once: true },
|
||||
);
|
||||
}),
|
||||
@@ -490,3 +493,17 @@ describe("runBrowserProxyCommand", () => {
|
||||
expect(dispatcherMocks.dispatch).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -45,11 +45,14 @@ function waitForAbort(
|
||||
cleanup: () => void;
|
||||
} {
|
||||
if (signal.aborted) {
|
||||
return { promise: Promise.reject(signal.reason ?? fallback), cleanup: () => undefined };
|
||||
return {
|
||||
promise: Promise.reject(toLintErrorObject(signal.reason ?? fallback, "Non-Error rejection")),
|
||||
cleanup: () => undefined,
|
||||
};
|
||||
}
|
||||
let listener: (() => void) | undefined;
|
||||
const promise = new Promise<never>((_, reject) => {
|
||||
listener = () => reject(signal.reason ?? fallback);
|
||||
listener = () => reject(toLintErrorObject(signal.reason ?? fallback, "Non-Error rejection"));
|
||||
signal.addEventListener("abort", listener, { once: true });
|
||||
});
|
||||
return {
|
||||
@@ -82,3 +85,17 @@ export async function withTimeout<T>(
|
||||
abort.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ export async function startBrowserControlServerFromConfig(): Promise<BrowserServ
|
||||
const server = await new Promise<Server>((resolve, reject) => {
|
||||
const s = app.listen(port, "127.0.0.1", () => resolve(s));
|
||||
s.once("error", reject);
|
||||
}).catch((err) => {
|
||||
}).catch((err: unknown) => {
|
||||
logServer.error(`openclaw browser server failed to bind 127.0.0.1:${port}: ${String(err)}`);
|
||||
return null;
|
||||
});
|
||||
|
||||
@@ -193,8 +193,6 @@ async function pollBytePlusTask(params: {
|
||||
throw new Error(
|
||||
readBytePlusErrorMessage(payload.error) || "BytePlus video generation failed",
|
||||
);
|
||||
case "queued":
|
||||
case "running":
|
||||
default:
|
||||
await waitProviderOperationPollInterval({ deadline, pollIntervalMs: POLL_INTERVAL_MS });
|
||||
break;
|
||||
|
||||
@@ -222,7 +222,9 @@ async function main() {
|
||||
}
|
||||
|
||||
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
||||
await main().catch((error) => {
|
||||
fail(error instanceof Error ? error.message : String(error));
|
||||
});
|
||||
await main().catch(
|
||||
/** @param {unknown} error */ (error) => {
|
||||
fail(error instanceof Error ? error.message : String(error));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -42,8 +42,10 @@ async function main() {
|
||||
}
|
||||
|
||||
if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
|
||||
main().catch((err) => {
|
||||
console.error(String(err));
|
||||
process.exit(1);
|
||||
});
|
||||
main().catch(
|
||||
/** @param {unknown} err */ (err) => {
|
||||
console.error(String(err));
|
||||
process.exit(1);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -487,7 +487,7 @@ export async function startCanvasHost(opts: CanvasHostServerOpts): Promise<Canva
|
||||
res.statusCode = 404;
|
||||
res.setHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
res.end("Not Found");
|
||||
})().catch((err) => {
|
||||
})().catch((err: unknown) => {
|
||||
opts.runtime.error(`Canvas host request failed: ${String(err)}`);
|
||||
res.statusCode = 500;
|
||||
res.setHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
|
||||
@@ -11,7 +11,7 @@ function formatErrorMessage(error: unknown): string {
|
||||
}
|
||||
|
||||
if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
|
||||
serveCodexSupervisorMcp().catch((err) => {
|
||||
serveCodexSupervisorMcp().catch((err: unknown) => {
|
||||
process.stderr.write(`codex-supervisor-serve: ${formatErrorMessage(err)}\n`);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -556,7 +556,7 @@ export class CodexNativeSubagentMonitor {
|
||||
childState.transcriptPollTimer = setTimeout(() => {
|
||||
childState.transcriptPollTimer = undefined;
|
||||
void this.reconcileChildTranscript(childState.childThreadId)
|
||||
.catch((error) => {
|
||||
.catch((error: unknown) => {
|
||||
embeddedAgentLog.warn("Failed to reconcile Codex native subagent transcript", {
|
||||
childThreadId: childState.childThreadId,
|
||||
error: formatErrorMessage(error),
|
||||
@@ -595,7 +595,7 @@ export class CodexNativeSubagentMonitor {
|
||||
}
|
||||
this.taskRowReconcileTimer = setInterval(
|
||||
() => {
|
||||
void this.reconcileKnownTaskRows().catch((error) => {
|
||||
void this.reconcileKnownTaskRows().catch((error: unknown) => {
|
||||
embeddedAgentLog.warn("Failed to reconcile Codex native subagent task rows", {
|
||||
error: formatErrorMessage(error),
|
||||
});
|
||||
|
||||
@@ -88,10 +88,10 @@ export async function waitForPluginApprovalDecision(params: {
|
||||
let onAbort: (() => void) | undefined;
|
||||
const abortPromise = new Promise<never>((_, reject) => {
|
||||
if (params.signal!.aborted) {
|
||||
reject(params.signal!.reason);
|
||||
reject(toLintErrorObject(params.signal!.reason, "Non-Error rejection"));
|
||||
return;
|
||||
}
|
||||
onAbort = () => reject(params.signal!.reason);
|
||||
onAbort = () => reject(toLintErrorObject(params.signal!.reason, "Non-Error rejection"));
|
||||
params.signal!.addEventListener("abort", onAbort, { once: true });
|
||||
});
|
||||
try {
|
||||
@@ -121,3 +121,17 @@ export function mapExecDecisionToOutcome(
|
||||
function truncateForGateway(value: string, maxLength: number): string {
|
||||
return value.length <= maxLength ? value : `${value.slice(0, Math.max(0, maxLength - 3))}...`;
|
||||
}
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1037,7 +1037,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
await vi.waitFor(
|
||||
() => {
|
||||
if (runError) {
|
||||
throw runError;
|
||||
throw toLintErrorObject(runError, "Non-Error thrown");
|
||||
}
|
||||
expect(harness.requests.map((request) => request.method)).toContain("turn/start");
|
||||
},
|
||||
@@ -1709,3 +1709,17 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
expect(maintain).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -696,7 +696,7 @@ describe("runCodexAppServerAttempt", () => {
|
||||
});
|
||||
|
||||
await expect(
|
||||
client.request("turn/start", turnParams).catch(async (error) => {
|
||||
client.request("turn/start", turnParams).catch(async (error: unknown) => {
|
||||
await releaseCodexSandboxExecServerEnvironment(sandbox);
|
||||
throw error;
|
||||
}),
|
||||
@@ -763,7 +763,7 @@ describe("runCodexAppServerAttempt", () => {
|
||||
nativeCodeModeOnlyEnabled: false,
|
||||
userMcpServersEnabled: false,
|
||||
environmentSelection,
|
||||
}).catch(async (error) => {
|
||||
}).catch(async (error: unknown) => {
|
||||
await releaseCodexSandboxExecServerEnvironment(sandbox);
|
||||
throw error;
|
||||
}),
|
||||
@@ -1237,7 +1237,7 @@ describe("runCodexAppServerAttempt", () => {
|
||||
params.prompt = "already persisted prompt";
|
||||
params.suppressNextUserMessagePersistence = true;
|
||||
const readTranscript = async () =>
|
||||
fs.readFile(sessionFile, "utf8").catch((error) => {
|
||||
fs.readFile(sessionFile, "utf8").catch((error: unknown) => {
|
||||
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -94,9 +94,11 @@ export function createCodexUserInputBridge(params: {
|
||||
resolvePending(emptyUserInputResponse());
|
||||
return;
|
||||
}
|
||||
void deliverUserInputPrompt(params.paramsForRun, requestParams.questions).catch((error) => {
|
||||
embeddedAgentLog.warn("failed to deliver codex user input prompt", { error });
|
||||
});
|
||||
void deliverUserInputPrompt(params.paramsForRun, requestParams.questions).catch(
|
||||
(error: unknown) => {
|
||||
embeddedAgentLog.warn("failed to deliver codex user input prompt", { error });
|
||||
},
|
||||
);
|
||||
});
|
||||
},
|
||||
handleQueuedMessage(text) {
|
||||
|
||||
@@ -388,22 +388,24 @@ async function withPluginMigrationEligibility(params: {
|
||||
return evaluated;
|
||||
}
|
||||
|
||||
const snapshot = await refreshSourceAppInventory(params.requestOptions).catch((error) => {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
for (const { plugin, apps } of pending) {
|
||||
evaluated.push({
|
||||
...plugin,
|
||||
migratable: false,
|
||||
migrationBlock: {
|
||||
code: "app_inventory_unavailable",
|
||||
apps,
|
||||
error: message,
|
||||
},
|
||||
message: `Codex plugin "${plugin.pluginName ?? plugin.name}" owns apps, but source app inventory could not be read: ${message}`,
|
||||
});
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
const snapshot = await refreshSourceAppInventory(params.requestOptions).catch(
|
||||
(error: unknown) => {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
for (const { plugin, apps } of pending) {
|
||||
evaluated.push({
|
||||
...plugin,
|
||||
migratable: false,
|
||||
migrationBlock: {
|
||||
code: "app_inventory_unavailable",
|
||||
apps,
|
||||
error: message,
|
||||
},
|
||||
message: `Codex plugin "${plugin.pluginName ?? plugin.name}" owns apps, but source app inventory could not be read: ${message}`,
|
||||
});
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
);
|
||||
if (!snapshot) {
|
||||
return evaluated;
|
||||
}
|
||||
|
||||
@@ -1396,7 +1396,7 @@ describe("runCopilotAttempt", () => {
|
||||
const sdk = makeFakeSdk();
|
||||
const pool = makeFakePool(sdk);
|
||||
pool.release = vi.fn(async () => {
|
||||
throw "release failed";
|
||||
throw toLintErrorObject("release failed", "Non-Error thrown");
|
||||
});
|
||||
|
||||
await expect(runCopilotAttempt(makeParams(), { pool })).rejects.toThrow("release failed");
|
||||
@@ -1414,7 +1414,7 @@ describe("runCopilotAttempt", () => {
|
||||
});
|
||||
const pool = makeFakePool(sdk);
|
||||
pool.release = vi.fn(async () => {
|
||||
throw "release failed";
|
||||
throw toLintErrorObject("release failed", "Non-Error thrown");
|
||||
});
|
||||
|
||||
const result = await runCopilotAttempt(makeParams(), { pool });
|
||||
@@ -2534,3 +2534,17 @@ describe("runCopilotAttempt", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ export function attachEventBridge(
|
||||
});
|
||||
deltaChain = deltaQueue.then(() => {
|
||||
if (firstDeltaError !== undefined) {
|
||||
throw firstDeltaError;
|
||||
throw toLintErrorObject(firstDeltaError, "Non-Error thrown");
|
||||
}
|
||||
});
|
||||
void deltaChain.catch(() => undefined);
|
||||
@@ -354,3 +354,17 @@ function registerListener<K extends SessionEventType>(
|
||||
session.off?.(eventType, handler as (...args: unknown[]) => void);
|
||||
});
|
||||
}
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -419,7 +419,7 @@ describe("createCopilotClientPool", () => {
|
||||
it("normalizes non-Error stop failures during dispose", async () => {
|
||||
const sdk = makeFake({
|
||||
stop: () => {
|
||||
throw "stop-string";
|
||||
throw toLintErrorObject("stop-string", "Non-Error thrown");
|
||||
},
|
||||
});
|
||||
const pool = createCopilotClientPool({ sdkFactory: sdk.fake });
|
||||
@@ -485,3 +485,17 @@ describe("createCopilotClientPool", () => {
|
||||
expect(String(sdk.ctorCalls[0]?.baseDirectory)).toBe(normalizedHome);
|
||||
});
|
||||
});
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ export async function loadCopilotSdk(options: LoadCopilotSdkOptions = {}): Promi
|
||||
|
||||
const promise = doLoad(options);
|
||||
if (useCache) {
|
||||
cached = promise.catch((err) => {
|
||||
cached = promise.catch((err: unknown) => {
|
||||
cached = undefined;
|
||||
throw err;
|
||||
});
|
||||
|
||||
@@ -204,7 +204,7 @@ describe("createTraceContextProvider", () => {
|
||||
const onError = vi.fn();
|
||||
const provider = createTraceContextProvider({
|
||||
getTraceparent: () => {
|
||||
throw "string-boom";
|
||||
throw toLintErrorObject("string-boom", "Non-Error thrown");
|
||||
},
|
||||
onError,
|
||||
});
|
||||
@@ -236,3 +236,17 @@ describe("createTraceContextProvider", () => {
|
||||
expect(getTraceparent).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -504,11 +504,11 @@ export function createPairingNotifierService(api: OpenClawPluginApi): OpenClawPl
|
||||
await notifyPendingPairingRequests({ api, statePath });
|
||||
};
|
||||
|
||||
await tick().catch((err) => {
|
||||
await tick().catch((err: unknown) => {
|
||||
api.logger.warn(`device-pair: initial notify poll failed: ${formatErrorMessage(err)}`);
|
||||
});
|
||||
notifyInterval = setInterval(() => {
|
||||
tick().catch((err) => {
|
||||
tick().catch((err: unknown) => {
|
||||
api.logger.warn(`device-pair: notify poll failed: ${formatErrorMessage(err)}`);
|
||||
});
|
||||
}, NOTIFY_POLL_INTERVAL_MS);
|
||||
|
||||
@@ -331,7 +331,7 @@ async function resolveBrowserExecutablePath(config: OpenClawConfig): Promise<str
|
||||
return await executablePathCache.valuePromise;
|
||||
}
|
||||
|
||||
const valuePromise = resolveBrowserExecutablePathUncached(config).catch((error) => {
|
||||
const valuePromise = resolveBrowserExecutablePathUncached(config).catch((error: unknown) => {
|
||||
if (executablePathCache?.valuePromise === valuePromise) {
|
||||
executablePathCache = null;
|
||||
}
|
||||
@@ -405,7 +405,7 @@ async function acquireSharedBrowser(params: {
|
||||
}
|
||||
return browser;
|
||||
})
|
||||
.catch((error) => {
|
||||
.catch((error: unknown) => {
|
||||
if (sharedBrowserState?.browserPromise === browserPromise) {
|
||||
sharedBrowserState = null;
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ export class DiffArtifactStore {
|
||||
|
||||
this.nextCleanupAt = now + this.cleanupIntervalMs;
|
||||
const cleanupPromise = this.cleanupExpired()
|
||||
.catch((error) => {
|
||||
.catch((error: unknown) => {
|
||||
this.nextCleanupAt = 0;
|
||||
this.logger?.warn(`Failed to clean expired diff artifacts: ${String(error)}`);
|
||||
})
|
||||
|
||||
@@ -163,7 +163,7 @@ describe("createDiscordRestClient proxy support", () => {
|
||||
},
|
||||
})
|
||||
.catch((err: unknown) => {
|
||||
reject(err);
|
||||
reject(toLintErrorObject(err, "Non-Error rejection"));
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
@@ -175,3 +175,17 @@ describe("createDiscordRestClient proxy support", () => {
|
||||
expect(received.body).toContain('"attachments":[{"id":0,"filename":"image.png"}]');
|
||||
});
|
||||
});
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,6 @@ export function mapButtonStyle(style?: DiscordComponentButtonStyle): ButtonStyle
|
||||
return ButtonStyle.Danger;
|
||||
case "link":
|
||||
return ButtonStyle.Link;
|
||||
case "primary":
|
||||
default:
|
||||
return ButtonStyle.Primary;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ export async function waitForDiscordGatewayStop(
|
||||
gateway?.disconnect?.();
|
||||
} finally {
|
||||
cleanup();
|
||||
reject(err);
|
||||
reject(toLintErrorObject(err, "Non-Error rejection"));
|
||||
}
|
||||
};
|
||||
const onAbort = () => {
|
||||
@@ -73,3 +73,17 @@ export async function waitForDiscordGatewayStop(
|
||||
params.registerForceStop?.(onForceStop);
|
||||
});
|
||||
}
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ export function queueInitialDiscordAckReaction(params: {
|
||||
if (!params.shouldSendAckReaction || !params.ackReaction) {
|
||||
return;
|
||||
}
|
||||
void params.reactionAdapter.setReaction(params.ackReaction).catch((err) => {
|
||||
void params.reactionAdapter.setReaction(params.ackReaction).catch((err: unknown) => {
|
||||
logAckFailure({
|
||||
log: logVerbose,
|
||||
channel: "discord",
|
||||
|
||||
@@ -239,7 +239,9 @@ function createGatewayPlugin(params: {
|
||||
info,
|
||||
usedFallback: false,
|
||||
}))
|
||||
.catch((error) => resolveGatewayInfoWithFallback({ runtime: params.runtime, error }));
|
||||
.catch((error: unknown) =>
|
||||
resolveGatewayInfoWithFallback({ runtime: params.runtime, error }),
|
||||
);
|
||||
this.gatewayInfo = resolved.info;
|
||||
this.gatewayInfoUsedFallback = resolved.usedFallback;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ export class DiscordMessageListener extends MessageCreateListener {
|
||||
// Per-session ordering is owned by the message run queue.
|
||||
void Promise.resolve()
|
||||
.then(() => this.handler(data, client))
|
||||
.catch((err) => {
|
||||
.catch((err: unknown) => {
|
||||
const logger = this.logger ?? discordEventQueueLog;
|
||||
logger.error(danger(`discord handler failed: ${String(err)}`));
|
||||
});
|
||||
@@ -68,7 +68,7 @@ export class DiscordInteractionListener extends InteractionCreateListener {
|
||||
// or compaction without blocking later gateway events.
|
||||
void Promise.resolve()
|
||||
.then(() => client.handleInteraction(data as Parameters<Client["handleInteraction"]>[0], {}))
|
||||
.catch((err) => {
|
||||
.catch((err: unknown) => {
|
||||
const logger = this.logger ?? discordEventQueueLog;
|
||||
logger.error(danger(`discord interaction handler failed: ${String(err)}`));
|
||||
});
|
||||
|
||||
@@ -113,7 +113,7 @@ function startAcceptedTypingFeedback(params: {
|
||||
};
|
||||
activeFeedback.set(dedupeKey, { channelId, feedback: replyTypingFeedback });
|
||||
ctx.replyTypingFeedback = replyTypingFeedback;
|
||||
void replyTypingFeedback.onReplyStart().catch((err) => {
|
||||
void replyTypingFeedback.onReplyStart().catch((err: unknown) => {
|
||||
logVerbose(`discord accepted typing feedback failed: ${String(err)}`);
|
||||
});
|
||||
return replyTypingFeedback;
|
||||
|
||||
@@ -267,7 +267,7 @@ async function fetchDiscordMedia(params: {
|
||||
fallbackContentType: params.fallbackContentType,
|
||||
originalFilename: params.originalFilename,
|
||||
...(signal ? { requestInit: { signal } } : {}),
|
||||
}).catch((error) => {
|
||||
}).catch((error: unknown) => {
|
||||
if (timedOut) {
|
||||
return new Promise<never>(() => {});
|
||||
}
|
||||
@@ -365,8 +365,6 @@ function resolveStickerAssetCandidates(sticker: APIStickerItem): DiscordStickerA
|
||||
fileName: `${baseName}.json`,
|
||||
},
|
||||
];
|
||||
case StickerFormatType.APNG:
|
||||
case StickerFormatType.PNG:
|
||||
default:
|
||||
return [
|
||||
{ url: `${DISCORD_STICKER_ASSET_BASE_URL}/${sticker.id}.png`, fileName: `${baseName}.png` },
|
||||
|
||||
@@ -727,7 +727,9 @@ describe("runDiscordGatewayLifecycle", () => {
|
||||
waitForDiscordGatewayStopMock.mockImplementationOnce(
|
||||
(params: WaitForDiscordGatewayStopParams) =>
|
||||
new Promise<void>((_resolve, reject) => {
|
||||
params.registerForceStop?.((err) => reject(err));
|
||||
params.registerForceStop?.((err) =>
|
||||
reject(toLintErrorObject(err, "Non-Error rejection")),
|
||||
);
|
||||
gateway.isConnected = false;
|
||||
emitter.emit("debug", "Gateway websocket opened");
|
||||
}),
|
||||
@@ -755,3 +757,17 @@ describe("runDiscordGatewayLifecycle", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ export async function writeVoiceWavFile(
|
||||
|
||||
function scheduleTempCleanup(tempDir: string, delayMs: number = 30 * 60 * 1000): void {
|
||||
const timer = setTimeout(() => {
|
||||
fs.rm(tempDir, { recursive: true, force: true }).catch((err) => {
|
||||
fs.rm(tempDir, { recursive: true, force: true }).catch((err: unknown) => {
|
||||
if (shouldLogVerbose()) {
|
||||
logVerbose(`discord voice: temp cleanup failed for ${tempDir}: ${formatErrorMessage(err)}`);
|
||||
}
|
||||
|
||||
@@ -221,7 +221,9 @@ function isUnknownDiscordVoiceStateError(err: unknown): boolean {
|
||||
function startAutoJoin(manager: Pick<DiscordVoiceManager, "autoJoin">) {
|
||||
void manager
|
||||
.autoJoin()
|
||||
.catch((err) => logger.warn(`discord voice: autoJoin failed: ${formatErrorMessage(err)}`));
|
||||
.catch((err: unknown) =>
|
||||
logger.warn(`discord voice: autoJoin failed: ${formatErrorMessage(err)}`),
|
||||
);
|
||||
}
|
||||
|
||||
function resolveDiscordVoiceAgentRoute(params: {
|
||||
@@ -782,7 +784,7 @@ export class DiscordVoiceManager {
|
||||
}
|
||||
|
||||
const speakingHandler: ((userId: string) => void) | undefined = (userId: string) => {
|
||||
void this.handleSpeakingStart(entry, userId).catch((err) => {
|
||||
void this.handleSpeakingStart(entry, userId).catch((err: unknown) => {
|
||||
logger.warn(`discord voice: capture failed: ${formatErrorMessage(err)}`);
|
||||
});
|
||||
};
|
||||
@@ -1134,7 +1136,7 @@ export class DiscordVoiceManager {
|
||||
return;
|
||||
}
|
||||
this.followUsersReconcileTimer = setInterval(() => {
|
||||
void this.reconcileFollowedUsers("interval").catch((err) => {
|
||||
void this.reconcileFollowedUsers("interval").catch((err: unknown) => {
|
||||
logger.warn(`discord voice: follow user reconciliation failed: ${formatErrorMessage(err)}`);
|
||||
});
|
||||
}, FOLLOW_USERS_RECONCILE_INTERVAL_MS);
|
||||
@@ -1176,7 +1178,7 @@ export class DiscordVoiceManager {
|
||||
this.params.client.rest,
|
||||
plan.guildId,
|
||||
userId,
|
||||
).catch((err) => {
|
||||
).catch((err: unknown) => {
|
||||
if (!isUnknownDiscordVoiceStateError(err)) {
|
||||
logger.warn(
|
||||
`discord voice: follow user reconcile skipped transient voice state error guild=${plan.guildId} user=${userId} reason=${reason}: ${formatErrorMessage(err)}`,
|
||||
@@ -1415,7 +1417,7 @@ export class DiscordVoiceManager {
|
||||
this.params.client.rest,
|
||||
guildId,
|
||||
this.botUserId,
|
||||
).catch((err) => {
|
||||
).catch((err: unknown) => {
|
||||
if (!isUnknownDiscordVoiceStateError(err)) {
|
||||
logger.warn(
|
||||
`discord voice: follow reconcile skipped transient bot voice state error guild=${guildId} reason=${reason}: ${formatErrorMessage(err)}`,
|
||||
@@ -1473,13 +1475,17 @@ export class DiscordVoiceManager {
|
||||
private enqueueProcessing(entry: VoiceSessionEntry, task: () => Promise<void>) {
|
||||
entry.processingQueue = entry.processingQueue
|
||||
.then(task)
|
||||
.catch((err) => logger.warn(`discord voice: processing failed: ${formatErrorMessage(err)}`));
|
||||
.catch((err: unknown) =>
|
||||
logger.warn(`discord voice: processing failed: ${formatErrorMessage(err)}`),
|
||||
);
|
||||
}
|
||||
|
||||
private enqueuePlayback(entry: VoiceSessionEntry, task: () => Promise<void>) {
|
||||
entry.playbackQueue = entry.playbackQueue
|
||||
.then(task)
|
||||
.catch((err) => logger.warn(`discord voice: playback failed: ${formatErrorMessage(err)}`));
|
||||
.catch((err: unknown) =>
|
||||
logger.warn(`discord voice: playback failed: ${formatErrorMessage(err)}`),
|
||||
);
|
||||
}
|
||||
|
||||
private clearCaptureFinalizeTimer(entry: VoiceSessionEntry, userId: string, generation?: number) {
|
||||
@@ -1789,7 +1795,7 @@ export class DiscordVoiceManager {
|
||||
return;
|
||||
}
|
||||
void this.recoverFromDecryptFailures(entry)
|
||||
.catch((recoverErr) =>
|
||||
.catch((recoverErr: unknown) =>
|
||||
logger.warn(`discord voice: decrypt recovery failed: ${formatErrorMessage(recoverErr)}`),
|
||||
)
|
||||
.finally(() => {
|
||||
|
||||
@@ -15,7 +15,7 @@ async function loadPdfEngine(): Promise<PdfEngine> {
|
||||
if (!pdfEnginePromise) {
|
||||
pdfEnginePromise = import("clawpdf")
|
||||
.then(({ createEngine }) => createEngine())
|
||||
.catch((err) => {
|
||||
.catch((err: unknown) => {
|
||||
pdfEnginePromise = null;
|
||||
throw new Error("Dependency clawpdf is required for PDF extraction", {
|
||||
cause: err,
|
||||
|
||||
@@ -112,7 +112,6 @@ export function resolveFeishuGroupSession(params: {
|
||||
})
|
||||
: buildFeishuConversationId({ chatId, scope: "group_sender", senderOpenId });
|
||||
break;
|
||||
case "group":
|
||||
default:
|
||||
peerId = chatId;
|
||||
break;
|
||||
|
||||
@@ -918,7 +918,7 @@ export async function handleFeishuMessage(params: {
|
||||
replyToMessageId: replyTargetMessageId,
|
||||
replyInThread: isGroup ? (groupSession?.replyInThread ?? false) : false,
|
||||
accountId: account.accountId,
|
||||
}).catch((err) => {
|
||||
}).catch((err: unknown) => {
|
||||
log(`feishu[${account.accountId}]: failed to send ACP init error reply: ${String(err)}`);
|
||||
});
|
||||
return;
|
||||
|
||||
@@ -37,7 +37,6 @@ export function buildFeishuConversationId(params: {
|
||||
return `${chatId}:topic:${topicId}`;
|
||||
}
|
||||
return senderOpenId ? `${chatId}:sender:${senderOpenId}` : chatId;
|
||||
case "group":
|
||||
default:
|
||||
return chatId;
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ function registerEventHandlers(
|
||||
const error = runtime?.error ?? console.error;
|
||||
const runFeishuHandler = async (params: { task: () => Promise<void>; errorMessage: string }) => {
|
||||
if (fireAndForget) {
|
||||
void params.task().catch((err) => {
|
||||
void params.task().catch((err: unknown) => {
|
||||
error(`${params.errorMessage}: ${String(err)}`);
|
||||
});
|
||||
return;
|
||||
@@ -417,7 +417,7 @@ function registerEventHandlers(
|
||||
accountId,
|
||||
});
|
||||
if (fireAndForget) {
|
||||
promise.catch((err) => {
|
||||
promise.catch((err: unknown) => {
|
||||
error(`feishu[${accountId}]: error handling card action: ${String(err)}`);
|
||||
});
|
||||
} else {
|
||||
|
||||
@@ -138,7 +138,7 @@ export function createFeishuBotMenuHandler(params: {
|
||||
}
|
||||
return await handleLegacyMenu();
|
||||
})
|
||||
.catch(async (err) => {
|
||||
.catch(async (err: unknown) => {
|
||||
if (isFeishuRetryableSyntheticEventError(err)) {
|
||||
await forgetProcessedFeishuMessage(syntheticMessageId, accountId, log);
|
||||
} else {
|
||||
@@ -150,7 +150,7 @@ export function createFeishuBotMenuHandler(params: {
|
||||
releaseFeishuMessageProcessing(syntheticMessageId, accountId);
|
||||
});
|
||||
if (fireAndForget) {
|
||||
promise.catch((err) => {
|
||||
promise.catch((err: unknown) => {
|
||||
error(`feishu[${accountId}]: error handling bot menu event: ${String(err)}`);
|
||||
});
|
||||
return;
|
||||
|
||||
@@ -35,7 +35,7 @@ export function createFeishuDriveCommentNoticeHandler(params: {
|
||||
const getBotOpenId = params.getBotOpenId ?? ((id) => botOpenIds.get(id));
|
||||
|
||||
const runFeishuHandler = async (task: () => Promise<void>) => {
|
||||
const promise = task().catch((err) => {
|
||||
const promise = task().catch((err: unknown) => {
|
||||
error(`feishu[${accountId}]: error handling drive comment notice: ${String(err)}`);
|
||||
});
|
||||
if (!fireAndForget) {
|
||||
|
||||
@@ -331,7 +331,7 @@ async function resolveParsedCommentContent(params: {
|
||||
resolvedObjToken: objToken,
|
||||
};
|
||||
})
|
||||
.catch((error) => {
|
||||
.catch((error: unknown) => {
|
||||
params.logger?.(
|
||||
`feishu[${params.accountId}]: wiki link resolution threw token=${link.wikiNodeToken} error=${formatErrorMessage(error)}`,
|
||||
);
|
||||
@@ -485,7 +485,7 @@ async function requestFeishuOpenApi<T>(params: {
|
||||
{ timeoutMs: params.timeoutMs },
|
||||
)
|
||||
.then((resolved) => (resolved.status === "resolved" ? resolved.value : null))
|
||||
.catch((error) => {
|
||||
.catch((error: unknown) => {
|
||||
params.logger?.(`${params.errorLabel}: ${formatErrorDetails(error)}`);
|
||||
return null;
|
||||
});
|
||||
|
||||
@@ -329,7 +329,7 @@ export function createFeishuMessageReceiveHandler({
|
||||
await inboundDebouncer.enqueue(event);
|
||||
};
|
||||
if (fireAndForget) {
|
||||
void processMessage().catch((err) => {
|
||||
void processMessage().catch((err: unknown) => {
|
||||
releaseFeishuMessageProcessing(messageDedupeKey, accountId);
|
||||
error(`feishu[${accountId}]: error handling message: ${String(err)}`);
|
||||
});
|
||||
|
||||
@@ -79,7 +79,7 @@ async function waitForSlowBodyTimeoutResponse(
|
||||
socket.setEncoding("utf8");
|
||||
socket.on("error", () => {});
|
||||
socket.on("data", (chunk) => {
|
||||
response += chunk;
|
||||
response += chunk.toString();
|
||||
if (response.includes("Request body timeout")) {
|
||||
clearTimeout(failTimer);
|
||||
socket.destroy();
|
||||
@@ -127,7 +127,7 @@ async function waitForOversizedBodyResponse(url: string): Promise<string> {
|
||||
|
||||
socket.setEncoding("utf8");
|
||||
socket.on("data", (chunk) => {
|
||||
response += chunk;
|
||||
response += chunk.toString();
|
||||
if (response.includes("Payload too large")) {
|
||||
finish(response);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ function resolveFeishuParentConversationCandidates(rawId: string): string[] {
|
||||
case "group_topic":
|
||||
case "group_sender":
|
||||
return [parsed.chatId];
|
||||
case "group":
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -520,7 +520,7 @@ export class FeishuStreamingSession {
|
||||
.then(async ({ release }) => {
|
||||
await release();
|
||||
})
|
||||
.catch((e) => this.log?.(`Note update failed: ${String(e)}`));
|
||||
.catch((e: unknown) => this.log?.(`Note update failed: ${String(e)}`));
|
||||
}
|
||||
|
||||
async close(finalText?: string, options?: { note?: string }): Promise<boolean> {
|
||||
@@ -584,7 +584,7 @@ export class FeishuStreamingSession {
|
||||
.then(async ({ release }) => {
|
||||
await release();
|
||||
})
|
||||
.catch((e) => this.log?.(`Close failed: ${String(e)}`));
|
||||
.catch((e: unknown) => this.log?.(`Close failed: ${String(e)}`));
|
||||
const finalState = this.state;
|
||||
this.state = null;
|
||||
this.pendingText = null;
|
||||
|
||||
@@ -144,7 +144,7 @@ export function handleGoogleMeetRealtimeConsultToolCall(params: {
|
||||
});
|
||||
params.session.submitToolResult(callId, result);
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
.catch((error: unknown) => {
|
||||
params.onTalkEvent?.({
|
||||
type: "tool.error",
|
||||
callId,
|
||||
|
||||
@@ -277,7 +277,7 @@ export async function startNodeAgentAudioBridge(params: {
|
||||
),
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
.catch((error: unknown) => {
|
||||
params.logger.warn(`[google-meet] node agent TTS failed: ${formatErrorMessage(error)}`);
|
||||
});
|
||||
};
|
||||
@@ -557,7 +557,7 @@ export async function startNodeRealtimeAudioBridge(params: {
|
||||
},
|
||||
timeoutMs: 5_000,
|
||||
})
|
||||
.catch((error) => {
|
||||
.catch((error: unknown) => {
|
||||
params.logger.warn(
|
||||
`[google-meet] node audio output failed: ${formatErrorMessage(error)}`,
|
||||
);
|
||||
@@ -580,7 +580,7 @@ export async function startNodeRealtimeAudioBridge(params: {
|
||||
},
|
||||
timeoutMs: 5_000,
|
||||
})
|
||||
.catch((error) => {
|
||||
.catch((error: unknown) => {
|
||||
params.logger.warn(
|
||||
`[google-meet] node audio clear failed: ${formatErrorMessage(error)}`,
|
||||
);
|
||||
|
||||
@@ -696,7 +696,7 @@ export async function startCommandAgentAudioBridge(params: {
|
||||
});
|
||||
endTalkTurn();
|
||||
})
|
||||
.catch((error) => {
|
||||
.catch((error: unknown) => {
|
||||
params.logger.warn(`[google-meet] agent TTS failed: ${formatErrorMessage(error)}`);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -68,7 +68,7 @@ async function createConnectedGatewayClient(
|
||||
reject(new Error("gateway event loop readiness timeout"));
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch((err: unknown) => {
|
||||
clearTimeout(timer);
|
||||
reject(err instanceof Error ? err : new Error(String(err)));
|
||||
});
|
||||
|
||||
@@ -140,7 +140,7 @@ describeLive("google plugin live", () => {
|
||||
}
|
||||
}
|
||||
if (lastError) {
|
||||
throw lastError;
|
||||
throw toLintErrorObject(lastError, "Non-Error thrown");
|
||||
}
|
||||
|
||||
expect(result?.provider).toBe("gemini");
|
||||
@@ -177,3 +177,17 @@ describeLive("google plugin live", () => {
|
||||
});
|
||||
}, 120_000);
|
||||
});
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -637,7 +637,12 @@ describe("google transport stream", () => {
|
||||
(_url: string, init?: RequestInit) =>
|
||||
new Promise<Response>((_resolve, reject) => {
|
||||
init?.signal?.addEventListener("abort", () => {
|
||||
reject(init.signal?.reason ?? new Error("aborted"));
|
||||
reject(
|
||||
toLintErrorObject(
|
||||
init.signal?.reason ?? new Error("aborted"),
|
||||
"Non-Error rejection",
|
||||
),
|
||||
);
|
||||
});
|
||||
}),
|
||||
)
|
||||
@@ -1984,3 +1989,17 @@ describe("google transport stream", () => {
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@ export function createGoogleChatWebhookRequestHandler(params: {
|
||||
|
||||
const dispatchTarget = selectedTarget;
|
||||
dispatchTarget.statusSink?.({ lastInboundAt: Date.now() });
|
||||
params.processEvent(parsedEvent, dispatchTarget).catch((err) => {
|
||||
params.processEvent(parsedEvent, dispatchTarget).catch((err: unknown) => {
|
||||
dispatchTarget.runtime.error?.(
|
||||
`[${dispatchTarget.account.accountId}] Google Chat webhook failed: ${String(err)}`,
|
||||
);
|
||||
|
||||
@@ -132,7 +132,7 @@ describe("monitorIMessageProvider watch.subscribe startup retry", () => {
|
||||
const monitorErrorPromise = monitorIMessageProvider({
|
||||
config: { channels: { imessage: {} } } as never,
|
||||
runtime: runtime as never,
|
||||
}).catch((error) => error);
|
||||
}).catch((error: unknown) => error);
|
||||
|
||||
await vi.runAllTimersAsync();
|
||||
const monitorError = await monitorErrorPromise;
|
||||
|
||||
@@ -1036,7 +1036,7 @@ export async function monitorIMessageProvider(opts: MonitorIMessageOpts = {}): P
|
||||
runtime,
|
||||
onNotification: (msg) => {
|
||||
if (msg.method === "message") {
|
||||
void handleMessage(msg.params).catch((err) => {
|
||||
void handleMessage(msg.params).catch((err: unknown) => {
|
||||
runtime.error?.(`imessage: handler failed: ${String(err)}`);
|
||||
});
|
||||
} else if (msg.method === "error") {
|
||||
|
||||
@@ -376,7 +376,7 @@ export async function connectIrcClient(options: IrcClientOptions): Promise<IrcCl
|
||||
text,
|
||||
rawLine,
|
||||
}),
|
||||
).catch((error) => {
|
||||
).catch((error: unknown) => {
|
||||
fail(error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -615,6 +615,20 @@ export async function handleLineWebhookEvents(
|
||||
}
|
||||
}
|
||||
if (firstError) {
|
||||
throw firstError;
|
||||
throw toLintErrorObject(firstError, "Non-Error thrown");
|
||||
}
|
||||
}
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -437,7 +437,7 @@ export async function monitorLineProvider(
|
||||
logVerbose(`line: received ${body.events.length} webhook events`);
|
||||
void Promise.resolve()
|
||||
.then(() => match.target.bot.handleWebhook(body))
|
||||
.catch((err) => {
|
||||
.catch((err: unknown) => {
|
||||
match.target.runtime.error?.(
|
||||
danger(`line webhook dispatch failed: ${String(err)}`),
|
||||
);
|
||||
|
||||
@@ -224,7 +224,7 @@ async function pushLineMessages(
|
||||
});
|
||||
|
||||
if (behavior.errorContext) {
|
||||
await pushRequest.catch((err) => {
|
||||
await pushRequest.catch((err: unknown) => {
|
||||
logLineHttpError(err, behavior.errorContext!);
|
||||
throw err;
|
||||
});
|
||||
@@ -301,7 +301,6 @@ export async function sendMessageLine(
|
||||
case "audio":
|
||||
messages.push(createAudioMessage(mediaUrl, opts.durationMs ?? 60000));
|
||||
break;
|
||||
case "image":
|
||||
default:
|
||||
// Backward compatibility: keep image as default when media kind is unspecified.
|
||||
{
|
||||
|
||||
@@ -128,7 +128,7 @@ export function createLineNodeWebhookHandler(params: {
|
||||
logVerbose(`line: received ${body.events.length} webhook events`);
|
||||
void Promise.resolve()
|
||||
.then(() => params.bot.handleWebhook(body))
|
||||
.catch((err) => logLineWebhookDispatchError(params.runtime, err));
|
||||
.catch((err: unknown) => logLineWebhookDispatchError(params.runtime, err));
|
||||
}
|
||||
} catch (err) {
|
||||
await receiveContext?.nack(err);
|
||||
|
||||
@@ -93,7 +93,7 @@ export function createLineWebhookMiddleware(
|
||||
logVerbose(`line: received ${body.events.length} webhook events`);
|
||||
void Promise.resolve()
|
||||
.then(() => onEvents(body))
|
||||
.catch((err) => logLineWebhookDispatchError(runtime, err));
|
||||
.catch((err: unknown) => logLineWebhookDispatchError(runtime, err));
|
||||
}
|
||||
} catch (err) {
|
||||
await receiveContext?.nack(err);
|
||||
|
||||
@@ -217,7 +217,7 @@ export function wrapLmstudioInferencePreload(ctx: ProviderWrapStreamFnContext):
|
||||
() => {
|
||||
recordPreloadSuccess(preloadKey);
|
||||
},
|
||||
(error) => {
|
||||
(error: unknown) => {
|
||||
const entry = recordPreloadFailure(preloadKey, Date.now());
|
||||
throw Object.assign(new Error("preload-failed"), {
|
||||
cause: error,
|
||||
|
||||
@@ -583,7 +583,12 @@ describe("createEmbeddedLobsterRunner", () => {
|
||||
);
|
||||
ctx?.signal?.addEventListener("abort", () => {
|
||||
clearTimeout(timeout);
|
||||
reject(ctx.signal?.reason ?? new Error("aborted"));
|
||||
reject(
|
||||
toLintErrorObject(
|
||||
ctx.signal?.reason ?? new Error("aborted"),
|
||||
"Non-Error rejection",
|
||||
),
|
||||
);
|
||||
});
|
||||
}),
|
||||
),
|
||||
@@ -605,3 +610,17 @@ describe("createEmbeddedLobsterRunner", () => {
|
||||
).rejects.toThrow(/timed out|aborted/);
|
||||
});
|
||||
});
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -286,9 +286,9 @@ async function withTimeout<T>(
|
||||
clearTimeout(timer);
|
||||
resolve(value);
|
||||
},
|
||||
(error) => {
|
||||
(error: unknown) => {
|
||||
clearTimeout(timer);
|
||||
reject(error);
|
||||
reject(toLintErrorObject(error, "Non-Error rejection"));
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -392,3 +392,17 @@ export function createEmbeddedLobsterRunner(options?: {
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ export class FileBackedMatrixSyncStore extends MemoryStore {
|
||||
}
|
||||
this.persistTimer = setTimeout(() => {
|
||||
this.persistTimer = null;
|
||||
void this.flush().catch((err) => {
|
||||
void this.flush().catch((err: unknown) => {
|
||||
LogService.warn("MatrixFileSyncStore", "Failed to persist Matrix sync store:", err);
|
||||
});
|
||||
}, PERSIST_DEBOUNCE_MS);
|
||||
|
||||
@@ -112,7 +112,7 @@ function createHarness(params?: {
|
||||
const runDetachedTask = vi.fn((_label: string, task: () => Promise<void>) => {
|
||||
const promise = Promise.resolve()
|
||||
.then(task)
|
||||
.catch((error) => {
|
||||
.catch((error: unknown) => {
|
||||
throw error;
|
||||
})
|
||||
.finally(() => {
|
||||
|
||||
@@ -230,7 +230,7 @@ export function registerMatrixMonitorEvents(params: {
|
||||
}
|
||||
return Promise.resolve()
|
||||
.then(task)
|
||||
.catch((error) => {
|
||||
.catch((error: unknown) => {
|
||||
logVerboseMessage(`matrix: ${label} failed (${String(error)})`);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -905,12 +905,14 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
if (!isPollEvent) {
|
||||
return null;
|
||||
}
|
||||
pollSnapshotPromise ??= fetchMatrixPollSnapshot(client, roomId, event).catch((err) => {
|
||||
logVerboseMessage(
|
||||
`matrix: failed resolving poll snapshot room=${roomId} id=${event.event_id ?? "unknown"}: ${String(err)}`,
|
||||
);
|
||||
return null;
|
||||
});
|
||||
pollSnapshotPromise ??= fetchMatrixPollSnapshot(client, roomId, event).catch(
|
||||
(err: unknown) => {
|
||||
logVerboseMessage(
|
||||
`matrix: failed resolving poll snapshot room=${roomId} id=${event.event_id ?? "unknown"}: ${String(err)}`,
|
||||
);
|
||||
return null;
|
||||
},
|
||||
);
|
||||
return await pollSnapshotPromise;
|
||||
};
|
||||
|
||||
@@ -1481,7 +1483,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
.then(({ reactMatrixMessage }) =>
|
||||
reactMatrixMessage(roomId, messageId, ackReaction, client),
|
||||
)
|
||||
.catch((err) => {
|
||||
.catch((err: unknown) => {
|
||||
logVerboseMessage(`matrix react failed for room ${roomId}: ${String(err)}`);
|
||||
});
|
||||
}
|
||||
@@ -1489,7 +1491,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
if (messageId) {
|
||||
loadMatrixSendModule()
|
||||
.then(({ sendReadReceiptMatrix }) => sendReadReceiptMatrix(roomId, messageId, client))
|
||||
.catch((err) => {
|
||||
.catch((err: unknown) => {
|
||||
logVerboseMessage(
|
||||
`matrix: read receipt failed room=${roomId} id=${messageId}: ${String(err)}`,
|
||||
);
|
||||
|
||||
@@ -281,7 +281,7 @@ export async function createMatrixInboundEventDeduper(params: {
|
||||
},
|
||||
ttlMs > 0 ? { ttlMs } : undefined,
|
||||
)
|
||||
.catch((err) => {
|
||||
.catch((err: unknown) => {
|
||||
LogService.warn(
|
||||
"MatrixInboundDedupe",
|
||||
"Failed persisting Matrix inbound dedupe entry:",
|
||||
|
||||
@@ -494,7 +494,7 @@ export async function monitorMatrixProvider(opts: MonitorMatrixOpts = {}): Promi
|
||||
auth,
|
||||
env: process.env,
|
||||
abortSignal: opts.abortSignal,
|
||||
}).catch((err) => {
|
||||
}).catch((err: unknown) => {
|
||||
logVerboseMessage(`matrix: failed to backfill deviceId after startup (${String(err)})`);
|
||||
});
|
||||
|
||||
|
||||
@@ -136,12 +136,14 @@ export async function handleInboundMatrixReaction(params: {
|
||||
return;
|
||||
}
|
||||
|
||||
const targetEvent = await params.client.getEvent(params.roomId, reaction.eventId).catch((err) => {
|
||||
params.logVerboseMessage(
|
||||
`matrix: failed resolving reaction target room=${params.roomId} id=${reaction.eventId}: ${String(err)}`,
|
||||
);
|
||||
return null;
|
||||
});
|
||||
const targetEvent = await params.client
|
||||
.getEvent(params.roomId, reaction.eventId)
|
||||
.catch((err: unknown) => {
|
||||
params.logVerboseMessage(
|
||||
`matrix: failed resolving reaction target room=${params.roomId} id=${reaction.eventId}: ${String(err)}`,
|
||||
);
|
||||
return null;
|
||||
});
|
||||
const targetSender =
|
||||
targetEvent && typeof targetEvent.sender === "string" ? targetEvent.sender.trim() : "";
|
||||
if (!targetSender) {
|
||||
|
||||
@@ -56,12 +56,14 @@ export function createMatrixReplyContextResolver(params: {
|
||||
return cached;
|
||||
}
|
||||
|
||||
const event = await params.client.getEvent(input.roomId, input.eventId).catch((err) => {
|
||||
params.logVerboseMessage(
|
||||
`matrix: failed resolving reply context room=${input.roomId} id=${input.eventId}: ${String(err)}`,
|
||||
);
|
||||
return null;
|
||||
});
|
||||
const event = await params.client
|
||||
.getEvent(input.roomId, input.eventId)
|
||||
.catch((err: unknown) => {
|
||||
params.logVerboseMessage(
|
||||
`matrix: failed resolving reply context room=${input.roomId} id=${input.eventId}: ${String(err)}`,
|
||||
);
|
||||
return null;
|
||||
});
|
||||
if (!event) {
|
||||
// Do not cache failures so transient errors can be retried on the next
|
||||
// message that references the same event.
|
||||
|
||||
@@ -9,7 +9,7 @@ export function createMatrixMonitorTaskRunner(params: {
|
||||
const runDetachedTask = (label: string, task: () => Promise<void>): Promise<void> => {
|
||||
const trackedTask: Promise<void> = Promise.resolve()
|
||||
.then(task)
|
||||
.catch((error) => {
|
||||
.catch((error: unknown) => {
|
||||
const message = String(error);
|
||||
params.logVerboseMessage(`matrix: ${label} failed (${message})`);
|
||||
params.logger.warn("matrix background task failed", {
|
||||
|
||||
@@ -74,7 +74,7 @@ export function createMatrixThreadContextResolver(params: {
|
||||
|
||||
const rootEvent = await params.client
|
||||
.getEvent(input.roomId, input.threadRootId)
|
||||
.catch((err) => {
|
||||
.catch((err: unknown) => {
|
||||
params.logVerboseMessage(
|
||||
`matrix: failed resolving thread root room=${input.roomId} id=${input.threadRootId}: ${String(err)}`,
|
||||
);
|
||||
|
||||
@@ -628,7 +628,7 @@ export function createMatrixVerificationEventRouter(params: {
|
||||
routeTask,
|
||||
);
|
||||
} else {
|
||||
void routeTask().catch((err) => {
|
||||
void routeTask().catch((err: unknown) => {
|
||||
params.logVerboseMessage(`matrix: failed routing verification event: ${String(err)}`);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -11,7 +11,11 @@ export async function clearAllIndexedDbState(params?: { databasePrefix?: string
|
||||
new Promise<void>((resolve, reject) => {
|
||||
const req = indexedDB.deleteDatabase(name);
|
||||
req.addEventListener("success", () => resolve(), { once: true });
|
||||
req.addEventListener("error", () => reject(req.error), { once: true });
|
||||
req.addEventListener(
|
||||
"error",
|
||||
() => reject(toLintErrorObject(req.error, "Non-Error rejection")),
|
||||
{ once: true },
|
||||
);
|
||||
req.addEventListener("blocked", () => resolve(), { once: true });
|
||||
}),
|
||||
),
|
||||
@@ -43,9 +47,17 @@ export async function seedDatabase(params: {
|
||||
db.close();
|
||||
resolve();
|
||||
});
|
||||
tx.addEventListener("error", () => reject(tx.error), { once: true });
|
||||
tx.addEventListener(
|
||||
"error",
|
||||
() => reject(toLintErrorObject(tx.error, "Non-Error rejection")),
|
||||
{ once: true },
|
||||
);
|
||||
});
|
||||
req.addEventListener("error", () => reject(req.error), { once: true });
|
||||
req.addEventListener(
|
||||
"error",
|
||||
() => reject(toLintErrorObject(req.error, "Non-Error rejection")),
|
||||
{ once: true },
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -82,9 +94,35 @@ export async function readDatabaseRecords(params: {
|
||||
values = valuesReq.result;
|
||||
maybeResolve();
|
||||
});
|
||||
keysReq.addEventListener("error", () => reject(keysReq.error), { once: true });
|
||||
valuesReq.addEventListener("error", () => reject(valuesReq.error), { once: true });
|
||||
keysReq.addEventListener(
|
||||
"error",
|
||||
() => reject(toLintErrorObject(keysReq.error, "Non-Error rejection")),
|
||||
{ once: true },
|
||||
);
|
||||
valuesReq.addEventListener(
|
||||
"error",
|
||||
() => reject(toLintErrorObject(valuesReq.error, "Non-Error rejection")),
|
||||
{ once: true },
|
||||
);
|
||||
});
|
||||
req.addEventListener("error", () => reject(req.error), { once: true });
|
||||
req.addEventListener(
|
||||
"error",
|
||||
() => reject(toLintErrorObject(req.error, "Non-Error rejection")),
|
||||
{ once: true },
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -97,7 +97,11 @@ function parseSnapshotPayload(data: string): IdbDatabaseSnapshot[] | null {
|
||||
function idbReq<T>(req: IDBRequest<T>): Promise<T> {
|
||||
return new Promise((resolve, reject) => {
|
||||
req.addEventListener("success", () => resolve(req.result), { once: true });
|
||||
req.addEventListener("error", () => reject(req.error), { once: true });
|
||||
req.addEventListener(
|
||||
"error",
|
||||
() => reject(toLintErrorObject(req.error, "Non-Error rejection")),
|
||||
{ once: true },
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -117,7 +121,9 @@ async function dumpIndexedDatabases(databasePrefix?: string): Promise<IdbDatabas
|
||||
const db: IDBDatabase = await new Promise((resolve, reject) => {
|
||||
const r = idb.open(name, version);
|
||||
r.addEventListener("success", () => resolve(r.result), { once: true });
|
||||
r.addEventListener("error", () => reject(r.error), { once: true });
|
||||
r.addEventListener("error", () => reject(toLintErrorObject(r.error, "Non-Error rejection")), {
|
||||
once: true,
|
||||
});
|
||||
});
|
||||
|
||||
const stores: IdbStoreSnapshot[] = [];
|
||||
@@ -203,7 +209,9 @@ async function restoreIndexedDatabases(snapshot: IdbDatabaseSnapshot[]): Promise
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
r.addEventListener("error", () => reject(r.error), { once: true });
|
||||
r.addEventListener("error", () => reject(toLintErrorObject(r.error, "Non-Error rejection")), {
|
||||
once: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -284,3 +292,17 @@ export async function persistIdbToDisk(params?: {
|
||||
LogService.warn("IdbPersistence", "Failed to persist IndexedDB snapshot:", err);
|
||||
}
|
||||
}
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -394,7 +394,7 @@ export class MatrixVerificationManager {
|
||||
.then(() => {
|
||||
this.touchVerificationSession(session);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch((err: unknown) => {
|
||||
session.acceptRequested = false;
|
||||
session.error = formatMatrixErrorMessage(err);
|
||||
this.touchVerificationSession(session);
|
||||
@@ -516,7 +516,7 @@ export class MatrixVerificationManager {
|
||||
.then(() => {
|
||||
this.touchVerificationSession(session);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch((err: unknown) => {
|
||||
session.error = formatMatrixErrorMessage(err);
|
||||
this.touchVerificationSession(session);
|
||||
});
|
||||
@@ -545,7 +545,7 @@ export class MatrixVerificationManager {
|
||||
.then(() => {
|
||||
this.touchVerificationSession(session);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch((err: unknown) => {
|
||||
session.error = formatMatrixErrorMessage(err);
|
||||
this.touchVerificationSession(session);
|
||||
});
|
||||
|
||||
@@ -35,10 +35,24 @@ export async function awaitMatrixStartupWithAbort<T>(
|
||||
abortSignal.removeEventListener("abort", onAbort);
|
||||
resolve(value);
|
||||
},
|
||||
(error) => {
|
||||
(error: unknown) => {
|
||||
abortSignal.removeEventListener("abort", onAbort);
|
||||
reject(error);
|
||||
reject(toLintErrorObject(error, "Non-Error rejection"));
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
|
||||
if (value instanceof Error) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return new Error(value);
|
||||
}
|
||||
const error = new Error(fallbackMessage, { cause: value });
|
||||
if ((typeof value === "object" && value !== null) || typeof value === "function") {
|
||||
Object.assign(error, value);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -368,7 +368,7 @@ export async function createMatrixThreadBindingManager(params: {
|
||||
};
|
||||
const persist = async () => await enqueuePersist();
|
||||
const persistSafely = (reason: string, bindings?: MatrixThreadBindingRecord[]) => {
|
||||
void enqueuePersist(bindings).catch((err) => {
|
||||
void enqueuePersist(bindings).catch((err: unknown) => {
|
||||
params.logVerboseMessage?.(
|
||||
`matrix: failed persisting thread bindings account=${params.accountId} action=${reason}: ${String(err)}`,
|
||||
);
|
||||
@@ -383,7 +383,7 @@ export async function createMatrixThreadBindingManager(params: {
|
||||
await persist();
|
||||
}
|
||||
await migrationStore.register(legacyImportKey, { importedAt: Date.now() });
|
||||
await fs.rm(legacyFilePath, { force: true }).catch((err) => {
|
||||
await fs.rm(legacyFilePath, { force: true }).catch((err: unknown) => {
|
||||
params.logVerboseMessage?.(
|
||||
`matrix: failed removing migrated legacy thread bindings account=${params.accountId}: ${String(err)}`,
|
||||
);
|
||||
@@ -693,7 +693,7 @@ export async function createMatrixThreadBindingManager(params: {
|
||||
await sendFarewellMessages(removed, (record) =>
|
||||
reasonByBindingKey.get(resolveBindingKey(record)),
|
||||
);
|
||||
})().catch((err) => {
|
||||
})().catch((err: unknown) => {
|
||||
params.logVerboseMessage?.(
|
||||
`matrix: failed auto-unbinding expired bindings account=${params.accountId}: ${String(err)}`,
|
||||
);
|
||||
|
||||
@@ -2165,7 +2165,7 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
client,
|
||||
commands,
|
||||
log: (msg) => runtime.log?.(msg),
|
||||
}).catch((err) => {
|
||||
}).catch((err: unknown) => {
|
||||
runtime.error?.(`mattermost: slash cleanup failed: ${String(err)}`);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -500,8 +500,8 @@ export function formatBackfillDiaryDate(isoDay: string, _timezone?: string): str
|
||||
}
|
||||
|
||||
async function assertSafeDreamsPath(dreamsPath: string): Promise<void> {
|
||||
const stat = await fs.lstat(dreamsPath).catch((err: NodeJS.ErrnoException) => {
|
||||
if (err.code === "ENOENT") {
|
||||
const stat = await fs.lstat(dreamsPath).catch((err: unknown) => {
|
||||
if (extractErrorCode(err) === "ENOENT") {
|
||||
return null;
|
||||
}
|
||||
throw err;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { extractErrorCode } from "openclaw/plugin-sdk/error-runtime";
|
||||
|
||||
type DreamingArtifactsAuditIssue = {
|
||||
severity: "warn" | "error";
|
||||
@@ -87,8 +88,8 @@ function buildArchiveTimestamp(now: Date): string {
|
||||
}
|
||||
|
||||
async function ensureArchivablePath(targetPath: string): Promise<"file" | "dir" | null> {
|
||||
const stat = await fs.lstat(targetPath).catch((err: NodeJS.ErrnoException) => {
|
||||
if (err.code === "ENOENT") {
|
||||
const stat = await fs.lstat(targetPath).catch((err: unknown) => {
|
||||
if (extractErrorCode(err) === "ENOENT") {
|
||||
return null;
|
||||
}
|
||||
throw err;
|
||||
|
||||
@@ -860,7 +860,7 @@ export function registerShortTermPromotionDreaming(api: OpenClawPluginApi): void
|
||||
}
|
||||
scheduleStartupCronRetry();
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch((err: unknown) => {
|
||||
if (disposed) {
|
||||
return;
|
||||
}
|
||||
@@ -877,7 +877,7 @@ export function registerShortTermPromotionDreaming(api: OpenClawPluginApi): void
|
||||
return;
|
||||
}
|
||||
runtimeCronReconcileTimer = setInterval(() => {
|
||||
void reconcileManagedDreamingCron({ reason: "runtime" }).catch((err) => {
|
||||
void reconcileManagedDreamingCron({ reason: "runtime" }).catch((err: unknown) => {
|
||||
api.logger.error(`memory-core: dreaming cron reconcile failed: ${formatErrorMessage(err)}`);
|
||||
});
|
||||
}, RUNTIME_CRON_RECONCILE_INTERVAL_MS);
|
||||
|
||||
@@ -8,7 +8,7 @@ export function startAsyncSearchSync(params: {
|
||||
if (!params.enabled || (!params.dirty && !params.sessionsDirty)) {
|
||||
return;
|
||||
}
|
||||
void params.sync({ reason: "search" }).catch((err) => {
|
||||
void params.sync({ reason: "search" }).catch((err: unknown) => {
|
||||
params.onError(err);
|
||||
});
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user