-
-
Notifications
You must be signed in to change notification settings - Fork 594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(wasm): rejecting with error on node.js file read #1346
Conversation
What can we do to protect against a regression (e.g. "hey this doesn't do anything on the runtime I'm using, let's remove useless code, for some reason") without a test? At the very least, we should have a thorough code comment that documents what runtimes will do what behavior and a warning not to remove the |
31acbc3
to
7117524
Compare
I was able to write a test, but it required fixing an existing test that wasn't executing. Hopefully this is ok. I've updated the description so that it is more accurate (the problem is that the type error is an uncaught exception, which can obscure the rejected promise). Thanks for the patience 😄 |
7117524
to
5c21031
Compare
When node.js is reading the wasm file and encounters an error (like if the file doesn't exist or user doesn't have permissions to read). It will still try and call `_instantiateOrCompile` with `undefined`, which results in an uncaught exception, possibly obscuring the error. As instead of the file read error, the following error will return: > TypeError: WebAssembly.compile(): Argument 0 must be a buffer source This can be replicated with the following script (don't execute at a REPL): ```js (async () => { await new Promise((resolve, reject) => { reject(new Error("permission error")); resolve(WebAssembly.compile(undefined)); }); })(); ``` Node.js will exit with an error code and print only the type error to stderr. If we try and catch the error at the outer level ```js (async () => { try { await new Promise((resolve, reject) => { reject(new Error("permission error")); resolve(WebAssembly.compile(undefined)); }); } catch (ex) { console.log(`this is the error: ${ex}`) } })(); ``` The log statement will exclude the type error: > this is the error: Error: permission error But node.js will still exit with an error code and the type error is printed to stderr. This is the behavior of node.js default [uncaught exception handler](https://nodejs.org/api/process.html#event-uncaughtexception) > By default, Node.js handles such exceptions by printing the stack trace to stderr and exiting with code 1 This commit avoids the uncaught exception by only invoking `resolve` behind a conditional on an absent error. This commit doesn't change the status of the promise as calling `resolve` after `reject`, while legal, doesn't really do anything [(ref)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise#description): > Only the first call to `resolveFunc` or `rejectFunc` affects the promise's > eventual state, and subsequent calls to either function can neither change the > fulfillment value/rejection reason nor toggle its eventual state from > "fulfilled" to "rejected" or opposite So depending on the runtime and how the user is overriding the default handler, uncaught exceptions may be handled differently. The test executes in a worker so that it can require the appropiate node js modules. I saw that another Wasm test used a worker, but would never execute as require is not defined, so this commit also fixes that test case.
5c21031
to
749728c
Compare
Rollup Plugin Name:
wasm
This PR contains:
Are tests included?
Breaking Changes?
Description
When node.js is reading the wasm file and encounters an error (like if the file doesn't exist or user doesn't have permissions to read). It will still try and call
_instantiateOrCompile
withundefined
, which results in an uncaught exception, possibly obscuring the error. As instead of the file read error, the following error will return:This can be replicated with the following script (don't execute at a REPL):
Node.js will exit with an error code and print only the type error to stderr.
If we try and catch the error at the outer level
The log statement will exclude the type error:
But node.js will still exit with an error code and the type error is printed to stderr.
This is the behavior of node.js default uncaught exception handler
This commit avoids the uncaught exception by only invoking
resolve
behind a conditional on an absent error.This commit doesn't change the status of the promise as calling
resolve
afterreject
, while legal, doesn't really do anything (ref):So depending on the runtime and how the user is overriding the default handler, uncaught exceptions may be handled differently
The test executes in a worker so that it can require the appropriate node js modules. I saw that another Wasm test used a worker, but would never execute as require is not defined, so this commit also fixes that test case.