Skip to content

Conversation

brandonocasey
Copy link

Fixes #40

@brandonocasey brandonocasey force-pushed the fix/respect-process.exitCode branch from 6bf3940 to 9eb516e Compare June 24, 2025 18:40
@brandonocasey brandonocasey force-pushed the fix/respect-process.exitCode branch from 9eb516e to db42728 Compare June 24, 2025 18:43
@sindresorhus
Copy link
Owner

AI review:

The Problem with the Current Patch

The patch always prioritizes process.exitCode over signal-based exit codes, but this might not be the right behavior. Consider these scenarios:

  1. User sets process.exitCode = 1 for normal exit handling
  2. Process gets killed by SIGTERM (signal 15)
  3. Current patch would exit with code 1 instead of 143 (128 + 15)

This loses important information about how the process died. Unix convention uses 128 + signal specifically to distinguish signal-based exits from normal exits.

Better Approach

The intention should probably be more nuanced:

// Respect process.exitCode for graceful exits, but preserve signal info for real signals
const exitCode = (signal > 0) 
  ? 128 + signal  // Real signal - preserve signal-based exit code
  : (typeof process.exitCode === 'number' || typeof process.exitCode === 'string') 
    ? process.exitCode 
    : 0;

Or alternatively, only respect process.exitCode for explicit exits:

const exitCode = (signal === 0 || signal === -128) // exit event or gracefulExit
  ? (typeof process.exitCode === 'number' || typeof process.exitCode === 'string') 
    ? process.exitCode 
    : 0
  : 128 + signal;

The Question

Should process.exitCode = 1 be ignored when the process is killed by SIGTERM? I think it probably should be - the signal-based exit code (143) carries more important information about the termination cause.

@brandonocasey brandonocasey force-pushed the fix/respect-process.exitCode branch from aff90fd to 1cada42 Compare September 8, 2025 08:39
@brandonocasey
Copy link
Author

brandonocasey commented Sep 8, 2025

The current failure on node 20 is happening for me even in main. The listener appears to be:

function flushSync() {
  workerStdio.stdout[kStdioWantsMoreDataCallback]();
  workerStdio.stderr[kStdioWantsMoreDataCallback]();
}

which comes from node internals: https://github.com/nodejs/node/blob/34cb10b4a25a920b9d38daff64ce4467a996bfc5/lib/internal/bootstrap/switches/is_not_main_thread.js#L49
Seems like the tests need an update in a different pull request. Unless you want me to update them here?

@sindresorhus
Copy link
Owner

You can just update here.

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.

process.exitCode is ignore
2 participants