Commit activity
Last 12 weeks · 69 commits
Community health
4 of 6 standards met
Recent PRs & issues
Synchronous iterator helpers just landed in Node 22. Async iterator helpers are currently a stage 2 ES proposal. Once they land in Node, we should add some tests, and document how to use them with Execa. They could be quite nice to use with Execa. For example: Note: , and would also be useful to get a quick return value while the subprocess is still running. However, those won't wait for the subprocess to complete, so the user would need to call , unlike the other iterator methods. Also, those could be used with .
Recent fixes
Just ran into this. The following call escapes the character, which prevents the shell from actually doing the pipe. The shows the command is being run as: note how the pipe is escaped. Edit: I know that using is not recommended, but I do piping of large amounts of data on limited resource machines, and the performance overhead of NodeJS stream piping is quite significant compared to a plain shell pipe between two processes, even with .
When a process has run out of file descriptors, throws a synchronously instead of returning a subprocess whose promise rejects. Node then emits the real spawn error on the next tick with no listener attached, and that unhandled event ends the process, even when the caller has caught the . Reproduction Linux, using from util-linux: Output with execa 10.0.1 and Node 22.23.1 on Fedora 44 (exit code 1, is never printed): For comparison, the other paths behave as expected: throws , and the process keeps running. without the lowered limit rejects with , and the process keeps running. A plain with an listener returns a child whose is , receives on the listener, and the process keeps running. Cause On and , Node's queues the error for the next tick and returns before it sets up (lib/internal/child_process.js#L405-L408). only catches errors thrown by itself, and then reads right after its block (lib/methods/main-async.js#L104). That read throws the before any listener is attached to the subprocess. Expected The same handling as other spawn errors: returns instead of throwing when fails with or . The returned promise rejects with an whose is or , as and already do. The spawn error is never an unhandled event. The change should be small: one branch in for a subprocess without that waits for its event and rejects with it, plus a test.
Problem When a subprocess cannot be spawned, and disagree about its output: Same for a that does not exist, and for every shape of the option: is also not what the documentation promises: is when the file descriptor is //a /an integer, or when is — not when the subprocess failed to start. So throws, and only in the synchronous methods, on exactly the path where error handling matters most. Cause The asynchronous methods get this right by accident: fails asynchronously, so the streams exist and are collected as empty. instead reports , and turns that into — an array of : https://github.com/sindresorhus/execa/blob/main/lib/io/output-sync.js Fix Build the empty output from the file descriptors instead, so the existing options keep deciding its shape: , , , a or an integer stay as documented; gives an empty ; and object mode give ; otherwise . The hardcoded length of 3 also becomes the real number of file descriptors. I have this implemented with tests here, if it is useful: https://github.com/yu2971512385-ui/execa/tree/fix/sync-spawn-failure-output** It adds twelve cases to covering the table above for both methods (four fail on ), and all 21 combinations of {ENOENT, missing } × {default, , , , , , } then agree between the two methods. is green (5137 tests) and is clean on the touched files. I left the path alone, where / throw outright on an invalid option, because pins as there. I could not open this as a pull request — is rejected for my account on this repository — so I am filing it here instead. Happy to send a PR if that gets enabled, or feel free to take the patch directly. AI assistance (Claude) was used to find this, by comparing against across option combinations, and to draft this report. I verified and tested every line.
Repository: sindresorhus/execa. Description: Process execution for humans Stars: 7623, Forks: 2755. Primary language: JavaScript. Languages: JavaScript (79.5%), TypeScript (20.5%). License: MIT. Topics: binary, child-process, exec, execute, javascript, nodejs, shell, spawn, spawned-processes, streams. Latest release: v10.2.0 (3d ago). Open PRs: 0, open issues: 1. Last activity: 3d ago. Community health: 85%. Top contributors: ehmicky, sindresorhus, SamVerschueren, jamestalmage, GMartigny, kevva, mk-pmb, fisker, aaronccasanova, justsml and others.