Skip to content
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

solc-js throws a massive error on unhandled promise rejection #12228

Closed
smartcontracts opened this issue Nov 3, 2021 · 12 comments
Closed

solc-js throws a massive error on unhandled promise rejection #12228

smartcontracts opened this issue Nov 3, 2021 · 12 comments

Comments

@smartcontracts
Copy link

solc-js throws a massive error on unhandled promise rejections. Here's a simple script you can use to reproduce:

const solc = require('solc')

const main = async () => {
  throw new Error('asdf')
}

main()

Running this script will dump entire source of soljson.js to your terminal. soljson.js throws the following RuntimeError:

RuntimeError: abort(Error: asdf). Build with -s ASSERTIONS=1 for more info.
    at process.abort (/home/k/Projects/work/random/solcjs-test/node_modules/solc/soljson.js:1:13012

NodeJS wants to show you the line on which the error was triggered but soljson.js is a minified file where the entire source is on a single line. As a result, it prints out the entire source of soljson.js. Upon cleaning up the file with js-beautify I no longer get the entire source dumped and get the following useful error:

k@kpc:~/Projects/work/random/solcjs-test$ node index.js 
Error: asdf
/home/k/Projects/work/random/solcjs-test/node_modules/solc/soljson.js:622
    throw e
    ^

RuntimeError: abort(Error: asdf). Build with -s ASSERTIONS=1 for more info.
    at process.abort (/home/k/Projects/work/random/solcjs-test/node_modules/solc/soljson.js:621:13)
    at process.emit (events.js:400:28)
    at processPromiseRejections (internal/process/promises.js:245:33)
    at processTicksAndRejections (internal/process/task_queues.js:96:32)

This error comes from the following function inside of soljson.js:

function abort(what) {
    if (Module["onAbort"]) {
        Module["onAbort"](what)
    }
    what += "";
    err(what);
    ABORT = true;
    EXITSTATUS = 1;
    what = "abort(" + what + "). Build with -s ASSERTIONS=1 for more info.";
    var e = new WebAssembly.RuntimeError(what);
    throw e
}

Which is triggered because of this listener:

    process["on"]("unhandledRejection", abort);

I've found various workarounds to this problem. One relatively easy workaround is to remove the listener:

const listeners = process.listeners('unhandledRejection')
process.removeListener('unhandledRejection', listeners[listeners.length - 1])

However, it would be great to have a canonical fix to this problem.

@cameel
Copy link
Member

cameel commented Nov 3, 2021

This seems to be an issue with emscripten and the binary it builds, not solc-js. I see that emscripten added the NODEJS_CATCH_REJECTION flag (emscripten-core/emscripten#9061) as a workaround. Maybe we should start using it when building but looks like there are some downsides. From https://github.com/haberbyte/emscripten/commit/bc370fed4dddfb705e71bd0ab719aa24e990252f:

  • Add NODEJS_CATCH_REJECTION, a flag that allows disabling the catching of unhandled rejections in node. This is useful if a dev doesn't want it to interfere with their own code. We don't set this to 0 by default because it would mean some wasm errors end up not returning a non-zero return code from node (still true as of 12.4.0)

So if we do this, we might have to at least bump the minimum node.js requirement. We might also need #11689 - we're on emscripten 2.0.12 now, released in January and the flag seems to have been added just after that release (changelog does not mention it though).

NodeJS wants to show you the line on which the error was triggered but soljson.js is a minified file where the entire source is on a single line. As a result, it prints out the entire source of soljson.js.

Right, this is very annoying. We seem to have some workarounds for it because I'm not seeing it as much in newer versions of solc-js and the compiler but when it does happen the output just obscures everything.

@ekpyron maybe we could use the --minify=0 with emscripten? The JS part in the binaries does not seem to be particularly big so I don't think it would add that much to the size and anyone who cares about size should compress them anyway (the binary part is very compressible).

@cameel
Copy link
Member

cameel commented Nov 3, 2021

Duplicate of ethereum/solc-js#505

@axic
Copy link
Member

axic commented Nov 3, 2021

Perhaps #11689 could fix it, as noted by @ekpyron.

@chriseth chriseth closed this as completed Nov 8, 2021
@chriseth chriseth reopened this Nov 8, 2021
@chriseth
Copy link
Contributor

chriseth commented Nov 8, 2021

Sorry, closed this because it said "duplicate"

@chriseth
Copy link
Contributor

chriseth commented Nov 8, 2021

So we had this issue before, didn't we? And we added some workarounds that look similar to the last one suggested in the description.

@cameel
Copy link
Member

cameel commented Nov 8, 2021

Yeah, it's technically a duplicate but this one had better description. I'd close the other one but I thought it being open in solc-js might help people who have this issue find the workaround. I'd be fine with just closing it though.

So we had this issue before, didn't we? And we added some workarounds that look similar to the last one suggested in the description.

We did - ethereum/solc-js#505 was reported in December 2020 - but I don't think we did anything in response to that. I can reproduce the problem on 0.8.9 which means it has no workaround.

@aniketpcsync
Copy link

Hey, you can take a look at this answer trufflesuite/ganache#2289 # #

@cameel

This comment was marked as outdated.

@cameel
Copy link
Member

cameel commented Feb 7, 2022

Ah, wait, it was not a question. So you're suggesting to use source maps? I'm not even sure we generate them. If we do, we discard them immediately. And I also think that disabling the minification would be much better than minifying and then having to ship source maps that negate all the speed and size benefits.

@NunoFilipeSantos
Copy link
Contributor

Hi @smartcontracts! 👋 We believe this issue is fixed on our newest versions, can you try to reproduce it?

@smartcontracts
Copy link
Author

Hi @smartcontracts! wave We believe this issue is fixed on our newest versions, can you try to reproduce it?

Nice! Can confirm this is fixed in versions >=0.8.12

@NunoFilipeSantos
Copy link
Contributor

Thank you for confirming. Cheers! 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants