Skip to content

Conversation

@ErickWendel
Copy link
Member

Description

Adds util.convertProcessSignalToExitCode() utility function to convert signal names (e.g., SIGTERM, SIGKILL) to their corresponding POSIX exit codes.

When a child process is terminated by a signal, the code parameter in the 'exit' and 'close' events is null. This utility allows users to convert the signal parameter to the POSIX standard exit code.

Example

import { spawn } from 'node:child_process';
import { once } from 'node:events';
import { convertProcessSignalToExitCode } from 'node:util';

const ls = spawn('ls', ['-lh', '/usr']);

ls.kill();

const [code, signal] = await once(ls, 'exit');
const exitCode = convertProcessSignalToExitCode(signal);
console.log(`signal ${signal}, POSIX exit code: ${exitCode}`);

// signal SIGTERM, POSIX exit code: 143

Note: While Windows doesn't natively support POSIX signals, Node.js provides a cross-platform abstraction that emulates signal behavior. This allows convertProcessSignalToExitCode() to work consistently across all platforms, returning the same POSIX exit codes on both Unix-like systems and Windows.

Refs

Add convertProcessSignalToExitCode() to convert signal names to POSIX
exit codes (128 + signal number). Exposed in public util API.

Refs: nodejs#60720
Document util.convertProcessSignalToExitCode() in child_process module
to help users convert signal names to POSIX exit codes when a child
process is terminated by a signal.

Refs: nodejs#60285
@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. util Issues and PRs related to the built-in util module. labels Dec 5, 2025
@RafaelGSS RafaelGSS added semver-minor PRs that contain new features and should be released in the next minor version. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. labels Dec 5, 2025
validateString(signalCode, 'signalCode');

const signalNumber = signals[signalCode];
if (signalNumber === undefined) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use validateOneOf here. e.g: https://github.com/nodejs/node/blob/main/lib/util.js#L149

console.log(`signal ${signal}, POSIX exit code: ${exitCode}`);

// signal SIGTERM, POSIX exit code: 143
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove the code samples and move the text to the bottom of the section – there's very little reason why somebody would want to do this, while information such as that stdio streams may still be open is much more directly relevant to what this event does

Comment on lines +1714 to +1718
**Note:** The `child_process` module does not automatically set `exitCode` when
a process is terminated by a signal to avoid breaking changes in existing code
that may depend on `exitCode` being `null` in such cases. The
[`util.convertProcessSignalToExitCode()`][] utility function is provided to
allow applications to opt-in to this conversion when needed.
Copy link
Member

@addaleax addaleax Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd drop this paragraph. Saying "we don't change this API because changing it would be a breaking change" applies to virtually any API we have. Providing a single link to util.convertProcessSignalToExitCode() should be sufficient (it's not something that people are going to need a lot). (EDIT: and maybe it makes more sense to link to that from the .signalCode docs than from the .exitCode docs?)

If the child process is still running, the field will be `null`.
When the child process is terminated by a signal, `subprocess.exitCode` will be
`null`. To get the corresponding POSIX exit code, use
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the really important thing we should mention is that subprocess.signalCode will be set, and we should link to that.

* Type: {string|null}
The `subprocess.signalCode` property indicates the signal received by
the child process if any, else `null`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might also be worth linking back to .exitCode from here

@codecov
Copy link

codecov bot commented Dec 5, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.53%. Comparing base (cbe0233) to head (51cfb9e).

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #60963   +/-   ##
=======================================
  Coverage   88.53%   88.53%           
=======================================
  Files         703      703           
  Lines      208413   208428   +15     
  Branches    40191    40198    +7     
=======================================
+ Hits       184521   184536   +15     
- Misses      15902    15909    +7     
+ Partials     7990     7983    -7     
Files with missing lines Coverage Δ
lib/internal/util.js 96.81% <100.00%> (+0.43%) ⬆️
lib/util.js 97.97% <100.00%> (+<0.01%) ⬆️

... and 47 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Labels

commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. needs-ci PRs that need a full CI run. semver-minor PRs that contain new features and should be released in the next minor version. util Issues and PRs related to the built-in util module.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants