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