Skip to content

Commit 65c2ad4

Browse files
committed
fix(@angular/build): safeguard Karma builder stream controller against closed state
When running Karma tests or when stream consumers (such as Architect test harness `executeOnce`) cancel the builder output stream early, both `ProgressNotifierReporter.onRunComplete` and `karma.Server` exit callbacks can attempt to enqueue results or close the `ReadableStreamController`. Under WHATWG Streams specification rules, calling `.enqueue()` or `.close()` on a controller whose `desiredSize` is `null` (closed or cancelled) throws `TypeError [ERR_INVALID_STATE]: Invalid state: Controller is already closed`. This change checks `controller.desiredSize !== null` and wraps enqueue/close calls in a try-catch block to gracefully handle closed controllers.
1 parent 9671cc6 commit 65c2ad4

2 files changed

Lines changed: 14 additions & 6 deletions

File tree

packages/angular/build/src/builders/karma/application_builder.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,14 @@ export function execute(
8585

8686
// Close the stream once the Karma server returns.
8787
karmaServer = new karma.Server(karmaConfig as Config, (exitCode) => {
88-
controller.enqueue({ success: exitCode === 0 });
89-
controller.close();
88+
if (controller.desiredSize !== null) {
89+
try {
90+
controller.enqueue({ success: exitCode === 0 });
91+
controller.close();
92+
} catch {
93+
// Stream controller may already be closed or cancelled
94+
}
95+
}
9096
});
9197

9298
await karmaServer.start();

packages/angular/build/src/builders/karma/progress-reporter.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,12 @@ export function injectKarmaReporter(
8181
}
8282

8383
onRunComplete = function (_browsers: unknown, results: RunCompleteInfo): void {
84-
if (results.exitCode === 0) {
85-
controller.enqueue({ success: true });
86-
} else {
87-
controller.enqueue({ success: false });
84+
if (controller.desiredSize !== null) {
85+
try {
86+
controller.enqueue({ success: results.exitCode === 0 });
87+
} catch {
88+
// Stream controller may already be closed or cancelled
89+
}
8890
}
8991
};
9092
}

0 commit comments

Comments
 (0)