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

Avoid crash when --openssl-legacy-provider or --max-old-space-size are set #3015

Closed
wants to merge 1 commit into from

Conversation

bitjson
Copy link
Contributor

@bitjson bitjson commented Apr 24, 2022

When nodeArguments includes either --openssl-legacy-provider or --max-old-space-size (e.g. --max-old-space-size=8192), testing fails with an internal error:

  ✖ Internal error
  Error [ERR_WORKER_INVALID_EXEC_ARGV]: Initiated Worker with invalid execArgv flags: --openssl-legacy-provider
  Error [ERR_WORKER_INVALID_EXEC_ARGV]: Initiated Worker with invalid execArgv flags: --openssl-legacy-provider
      at new NodeError (node:internal/errors:372:5)
      at new Worker (node:internal/worker:191:13)
      at createWorker (file:///.../ava/lib/fork.js:24:12)
      at loadFork (file:///.../ava/lib/fork.js:88:39)
      at pMap.concurrency.concurrency (file:///.../ava/lib/api.js:286:20)
      at file:///.../ava/node_modules/p-map/index.js:100:26
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

This happens for any execArgv options not supported by Workers:

V8 options (such as --max-old-space-size) and options that affect the process (such as --title) are not supported.

At least for --openssl-legacy-provider, the worker threads inherit the setting from the parent process anyways. In my case, I need --openssl-legacy-provider enabled to support ripemd160 hashing on Node v18.0.0:

/path/to/test.mjs:

import crypto from 'node:crypto';
console.log(`Empty ripemd160 hash: ${crypto.createHash('ripemd160').digest().toString('hex')}`);

Running node (without --openssl-legacy-provider), this test script throws an error:

❯ node
Welcome to Node.js v18.0.0.
Type ".help" for more information.
> new worker_threads.Worker('/path/to/test.mjs', {execArgv: ['--openssl-legacy-provider']})
Worker { ... }
> Uncaught Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:67:19)
    at Object.createHash (node:crypto:133:10)
    at file:///path/to/test.mjs:5:6
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:409:24)
    at async loadESM (node:internal/process/esm_loader:85:5)
    at async handleMainPromise (node:internal/modules/run_main:61:12) {
  opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED',
  domainEmitter: Worker { ... }

If we use node --openssl-legacy-provider, the test script works:

❯ node --openssl-legacy-provider
Welcome to Node.js v18.0.0.
Type ".help" for more information.
> console.log(`Empty ripemd160 hash: ${crypto.createHash('ripemd160').digest().toString('hex')}`);
Empty ripemd160 hash: 9c1185a5c5e9fc54612808977ee8f548b2258d31

However, attempting to pass --openssl-legacy-provider into Worker fails:

❯ node
Welcome to Node.js v18.0.0.
Type ".help" for more information.
> new worker_threads.Worker('/path/to/test.mjs', {execArgv: ['--openssl-legacy-provider']})
Uncaught:
Error [ERR_WORKER_INVALID_EXEC_ARGV]: Initiated Worker with invalid execArgv flags: --openssl-legacy-provider
    at __node_internal_captureLargerStackTrace (node:internal/errors:465:5)
    at new NodeError (node:internal/errors:372:5)
    at new Worker (node:internal/worker:191:13) {
  code: 'ERR_WORKER_INVALID_EXEC_ARGV'
}

But that's fine because the Worker inherits the --openssl-legacy-provider setting:

❯ node --openssl-legacy-provider
Welcome to Node.js v18.0.0.
Type ".help" for more information.
> new worker_threads.Worker('/path/to/test.mjs', {execArgv: ['']})
Worker { ... }
> Empty ripemd160 hash: 9c1185a5c5e9fc54612808977ee8f548b2258d31

This PR handles the issue in the same way as parcel-bundler/parcel#5017 – we can just filter out unsupported nodeArguments before passing them to Worker options.execArgv.

@bitjson bitjson marked this pull request as draft April 24, 2022 02:06
@bitjson
Copy link
Contributor Author

bitjson commented Apr 24, 2022

I somehow missed #2944 in my initial searches; using --no-worker-threads is probably a better choice for affected projects.

Also, this PR doesn't fully solve the issue (I wasn't testing it properly) – projects actually need to set the NODE_OPTIONS=--openssl-legacy-provider env variable for the main process to start with the setting.

I don't think there's a simple way to allow these options to be set in AVA's nodeArguments setting, but I suppose it could be possible to have a sort of wrapper CLI first load the nodeArguments setting from any configuration locations, then internally start the actual CLI with NODE_OPTIONS=... set properly. By default, options are inherited from the parent thread, so it may be possible to avoid needing to filter arguments before passing them to workers.

Anyways, this PR isn't the right solution – going to close for now.

@bitjson bitjson closed this Apr 24, 2022
@novemberborn
Copy link
Member

Interesting, I wasn't aware of this @bitjson. I agree when those arguments are used then worker threads need to be disabled. It seems like too much of an edge case to do that automatically. Perhaps though we should recognize the errors and print a more helpful message?

@bitjson
Copy link
Contributor Author

bitjson commented May 17, 2022

@novemberborn that would certainly have saved me time! Just some error message mentioning that I can use --no-worker-threads to use flags not supported by Workers. 👍

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

Successfully merging this pull request may close these issues.

2 participants