fix(coding-agent): kept unrelated worker failures fatal
Classified only marked browser failures and evaluated-run stack frames as run-owned rejections. Unrelated tab-worker failures now remain on the worker guard's fatal path.
This commit is contained in:
@@ -10,7 +10,7 @@ import { resolveToCwd } from "../../path-utils";
|
||||
import { formatScreenshot } from "../../render-utils";
|
||||
import {
|
||||
bindRunFacade,
|
||||
isBrowserRunRejection,
|
||||
isBrowserRunOwnedRejection,
|
||||
markBrowserRunRejection,
|
||||
observeBrowserRunPromise,
|
||||
resolvePredicateTimeout,
|
||||
@@ -1409,9 +1409,7 @@ export async function runCmuxCode(tab: CmuxTab, opts: RunCmuxCodeOptions): Promi
|
||||
rejectFloatingFailure(error);
|
||||
};
|
||||
const uninstallRejectionInterceptor = postmortem.interceptUnhandledRejections(reason => {
|
||||
const browserRunRejection = isBrowserRunRejection(reason, rejectionOwner);
|
||||
const stack = reason instanceof Error && typeof reason.stack === "string" ? reason.stack : undefined;
|
||||
if (!browserRunRejection && stack?.includes(`cmux-run-${runId}.js`) !== true) return false;
|
||||
if (!isBrowserRunOwnedRejection(reason, rejectionOwner, `cmux-run-${runId}.js`)) return false;
|
||||
recordFloatingFailure(reason);
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -24,7 +24,7 @@ import {
|
||||
bindRunFacade,
|
||||
CELL_BUDGET_SLACK_MS,
|
||||
installBrowserWorkerRejectionGuard,
|
||||
isBrowserRunRejection,
|
||||
isBrowserRunOwnedRejection,
|
||||
markBrowserRunRejection,
|
||||
markHandled,
|
||||
observeBrowserRunPromise,
|
||||
@@ -784,10 +784,7 @@ export class WorkerCore {
|
||||
#consumeUnhandledRejection(reason: unknown): boolean {
|
||||
const active = this.#active;
|
||||
if (!active) return false;
|
||||
const browserRunRejection = isBrowserRunRejection(reason, active.rejectionOwner);
|
||||
const stack = reason instanceof Error && typeof reason.stack === "string" ? reason.stack : undefined;
|
||||
const fromRun = stack?.includes(`browser-run-${active.id}.js`) === true;
|
||||
if (!browserRunRejection && !this.#isolated && !fromRun) return false;
|
||||
if (!isBrowserRunOwnedRejection(reason, active.rejectionOwner, `browser-run-${active.id}.js`)) return false;
|
||||
this.#recordFloatingRejection(active, reason);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,12 @@ export function isBrowserRunRejection(reason: unknown, owner: object): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
/** Returns whether a rejection belongs to the marked browser run or its evaluated source file. */
|
||||
export function isBrowserRunOwnedRejection(reason: unknown, owner: object, filename: string): boolean {
|
||||
if (isBrowserRunRejection(reason, owner)) return true;
|
||||
return reason instanceof Error && typeof reason.stack === "string" && reason.stack.includes(filename);
|
||||
}
|
||||
|
||||
type FloatingRejectionHandler = (reason: unknown) => void;
|
||||
|
||||
interface ObservedPromiseState {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { postmortem } from "@oh-my-pi/pi-utils";
|
||||
import { JsRuntime, type RuntimeHooks } from "../../src/eval/js/shared/runtime";
|
||||
import {
|
||||
bindRunFacade,
|
||||
isBrowserRunOwnedRejection,
|
||||
isBrowserRunRejection,
|
||||
markBrowserRunRejection,
|
||||
markHandled,
|
||||
@@ -147,6 +148,20 @@ describe("browser run cancellation", () => {
|
||||
expect(isBrowserRunRejection(new Error("unrelated", { cause: browserFailure }), owner)).toBe(false);
|
||||
});
|
||||
|
||||
it("keeps unrelated worker rejections outside the active browser run", () => {
|
||||
const owner = {};
|
||||
const workerFailure = new Error("transport failed");
|
||||
workerFailure.stack = "Error: transport failed\n at tab-worker.ts:1:1";
|
||||
const evaluatedFailure = new Error("evaluated failure");
|
||||
evaluatedFailure.stack = "Error: evaluated failure\n at browser-run-run-1.js:1:1";
|
||||
|
||||
expect(isBrowserRunOwnedRejection(workerFailure, owner, "browser-run-run-1.js")).toBe(false);
|
||||
expect(isBrowserRunOwnedRejection(evaluatedFailure, owner, "browser-run-run-1.js")).toBe(true);
|
||||
expect(
|
||||
isBrowserRunOwnedRejection(markBrowserRunRejection(workerFailure, owner), owner, "browser-run-run-1.js"),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps a later cause-wrapped rejection on the fatal path", async () => {
|
||||
vi.useRealTimers();
|
||||
const script = `
|
||||
|
||||
Reference in New Issue
Block a user