From 26038912f6ce55cf3ce887b6f522969febec6721 Mon Sep 17 00:00:00 2001 From: morluto <76467478+morluto@users.noreply.github.com> Date: Sun, 11 Oct 2026 07:36:39 +0800 Subject: [PATCH] fix(javascript): preserve cancellation during worker preparation --- .../javascript/JavaScriptApplicationCancellation.test.ts | 1 - src/javascript/analysis/JavaScriptAnalysisWorker.ts | 9 +++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/application/javascript/JavaScriptApplicationCancellation.test.ts b/src/application/javascript/JavaScriptApplicationCancellation.test.ts index f4424de5b9..aa2b7b9454 100644 --- a/src/application/javascript/JavaScriptApplicationCancellation.test.ts +++ b/src/application/javascript/JavaScriptApplicationCancellation.test.ts @@ -122,7 +122,6 @@ describe("JavaScript analysis cancellation before publication", () => { throw new Error("Cancelled analysis must not publish Evidence"); expect(projectAnalysisError(result.error)).toMatchObject({ code: "cancelled", - details: { reason: "cancelled" }, }); expect(terminal).toEqual([]); }); diff --git a/src/javascript/analysis/JavaScriptAnalysisWorker.ts b/src/javascript/analysis/JavaScriptAnalysisWorker.ts index f8c544c991..c88e9e091c 100644 --- a/src/javascript/analysis/JavaScriptAnalysisWorker.ts +++ b/src/javascript/analysis/JavaScriptAnalysisWorker.ts @@ -356,7 +356,7 @@ export class JavaScriptAnalysisWorker { break; } } catch (cause: unknown) { - const error = this.#failure(cause, file.path, deadline); + const error = this.#failure(cause, file.path, deadline, signal); this.#lastFailure = error; // Complete checkpoints remain readable after a child crash or cancellation. const cleanup = await this.#stop(error); @@ -632,8 +632,13 @@ export class JavaScriptAnalysisWorker { cause: unknown, path: string, deadline: ProviderStartupDeadline | undefined, + signal: AbortSignal | undefined, ): AnalysisError { - if (deadline?.interruption === "cancelled") + // Ownership preparation is abortable before the worker deadline exists. + if ( + deadline?.interruption === "cancelled" || + (deadline === undefined && signal?.aborted === true) + ) return new AnalysisCancelledError(OPERATION, { capturedOutput: this.#captured(), });