nodejs / nodejs/node

Add an option not to trap SIGINT (Ctrl + C) to `readline.creatInterface`

Open
#61,487 11 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

feature request
Dominant language
JavaScript
Stars
122k
Forks
37.3k
Avg merge
4d 2h
Merged PRs (30d)
283

Description

What is the problem this feature will solve?

Here is a typical code to accepts multiple lines from stdin:

import { stdin, stderr } from "node:process";
import { createInterface } from "node:readline/promises";

const rl = createInterface({ input: stdin, output: stderr });

for await (const line of rl) {
  // process line
}
console.log("Done");

However, if you press Ctrl + C, it is treated as Ctrl + D—i.e. "Done" is displayed and you cannot cancel the multiline input. It is a ridiculous behavior.

await rl.question() throws AbortError and messes up your terminal:

$ node ./test.mjs
node:internal/readline/interface:1331
            this[kQuestionReject]?.(new AbortError('Aborted with Ctrl+C'));
                                    ^

AbortError: Aborted with Ctrl+C
    at [_ttyWrite] (node:internal/readline/interface:1331:37)
    at ReadStream.onkeypress (node:internal/readline/interface:284:20)
    at ReadStream.emit (node:events:508:28)
    at emitKeys (node:internal/readline/utils:371:14)
    at emitKeys.next (<anonymous>)
    at ReadStream.onData (node:internal/readline/emitKeypressEvents:64:36)
    at ReadStream.emit (node:events:508:28)
    at addChunk (node:internal/streams/readable:559:12)
    at readableAddChunkPushByteMode (node:internal/streams/readable:510:3)
    at Readable.push (node:internal/streams/readable:390:5) {
  code: 'ABORT_ERR'
}

It is not sophisticated.

What is the feature you are proposing to solve the problem?

Add an option to creatInterface to prevent it from trapping SIGINT by default.

const rl = createInterface({ input: stdin, output: stderr, noTrapSigInt: true });

With this, you will be able to press Ctrl + C to terminate the program immediately with the proper exit code.

What alternatives have you considered?
import { platform } from "node:process";

rl.on("SIGINT", () => {
  process.exit(platform === "win32" ? -1073741510 : 130);
});

Why do I have to add such a code? Who the hell can remember such numbers for both platforms?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the createInterface entry point shown in the issue and trace how Ctrl+C is handled during multiline iteration and question prompts. Verify the requested option's behavior on the described platforms, then add coverage and documentation showing that Ctrl+C can terminate normally without the current trapping behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nodejs
Domain
cli
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.