Skip to content

Commit 489656a

Browse files
authored
Merge pull request #2016 from Automattic/fix/2010-worker-rejection-exit
Handle cross-realm PHP-WASM worker failures
2 parents c712739 + afe584d commit 489656a

3 files changed

Lines changed: 7 additions & 4 deletions

File tree

patches/@wp-playground+cli+3.1.46.patch

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ index 93b7099..65f76be 100644
66
}
77
process.on("unhandledRejection", (r) => {
88
S.error("Unhandled rejection:", r);
9-
+ if (r instanceof WebAssembly.RuntimeError && String(r.stack).includes("php.wasm"))
9+
+ if (r?.name === "RuntimeError" && String(r.stack).includes("php.wasm"))
1010
+ throw r;
1111
});
1212
const i = new _(), [c, p] = y(
@@ -19,7 +19,7 @@ index fb79a59..77ddb67 100644
1919
}
2020
process.on("unhandledRejection", (r) => {
2121
E.error("Unhandled rejection:", r);
22-
+ if (r instanceof WebAssembly.RuntimeError && String(r.stack).includes("php.wasm"))
22+
+ if (r?.name === "RuntimeError" && String(r.stack).includes("php.wasm"))
2323
+ throw r;
2424
});
2525
const i = new m(), [h, u] = k(

patches/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ contains the same change.
1111

1212
`@wp-playground+cli+3.1.46.patch` makes blueprint worker threads rethrow fatal
1313
`WebAssembly.RuntimeError` rejections originating from `php.wasm` after logging
14-
them. Other unhandled rejections retain the released CLI's log-only behavior.
14+
them. Detection uses the error name because PHP-WASM errors may cross JavaScript
15+
realm boundaries where `instanceof` is false. Other unhandled rejections retain
16+
the released CLI's log-only behavior.
1517
Without this narrow terminalization, a poisoned PHP-WASM worker remains alive
1618
and leaves the parent request pending until the recipe timeout. Remove the patch
1719
after the Playground CLI ships the same worker terminalization behavior.

tests/playground-worker-runtime-rejection.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ const preloadPath = join(root, "reject-on-command.mjs")
1010

1111
await writeFile(preloadPath, `
1212
import { parentPort } from "node:worker_threads"
13+
import { runInNewContext } from "node:vm"
1314
parentPort?.on("message", (message) => {
1415
if (message === "wp-codebox-trigger-non-wasm-rejection") {
1516
Promise.reject(new Error("ordinary worker rejection"))
1617
setTimeout(() => parentPort?.postMessage("wp-codebox-worker-survived"), 25)
1718
}
1819
if (message === "wp-codebox-trigger-php-wasm-rejection") {
19-
const error = new WebAssembly.RuntimeError("null function or function signature mismatch")
20+
const error = runInNewContext('new WebAssembly.RuntimeError("null function or function signature mismatch")')
2021
error.stack = "RuntimeError: null function or function signature mismatch\\n at php.wasm.zif_mysqli_poll (wasm://wasm/php.wasm-05996276:wasm-function[12986]:0x9949a8)"
2122
Promise.reject(error)
2223
}

0 commit comments

Comments
 (0)