Skip to content

[Bug]: Cannot capture SIGINT(Ctrl+C) #2112

@colinaaa

Description

@colinaaa

Version

npmPackages:
    @rsbuild/core: ^0.6.0 => 0.6.0 
    @rsbuild/plugin-react: ^0.6.0 => 0.6.0

Details

I would like to capture the SIGINT(Ctrl+C) in my app built with Rsbuild. After adding process.on('SIGINT', callback), it seems like the process still exits when Ctrl+C is pressed.

I took a look at the Rsbuild's code, Rsbuild is also listening to the 'SIGINT' signal and calls process.exit inside the callback.

process.on('SIGINT', () => {
process.exit(0);
});

I could remove the listener after the call to createRsbuild() and startDevServer() using process.removeAllListeners('SIGINT'). But this makes the code handling process exit split into two places:

  1. src/exit.js
import { asyncExitHook, gracefulExit } from 'exit-hook';
const unsubscribe = asyncExitHook(onExit, { wait: 1000 });
// Cannot do process.on('SIGINT') here.
process.on('unhandledRejection', async (reason) => {
    unsubscribe();
    await onExit(1);
    process.exit(1);
});
  1. src/rsbuild.js
const rsbuild = await createRsbuild({ cwd, rsbuildConfig })

const server = await rsbuild.createDevServer()

// Rsbuild has an exit listener on `SIGINT` and directly call process.exit(0)
// We remove it from here
process.removeAllListeners('SIGINT')

let interrupted = false
process.on('SIGINT', () => {
  if (interrupted) {
    return process.exit(/** 128 + 2(kill) */ 130)
  }

  interrupted = true
  logger.info(
    `Gracefully shutting down. Please wait... (Press ${
      color.cyan('Ctrl+C')
    } again to force exit)`,
  )

  exit(/** 128 + 2(kill) */ 130)
})

It would be nice if Rsbuild could remove this SIGINT exit listener. So that I could capture SIGINT in my exit.js.

Reproduce link

https://github.com/web-infra-dev/rsbuild/tree/main/examples/react

Reproduce Steps

  1. Use the simplest example
  2. Add a SIGINT listener in rsbuild.config.ts

E.g.:

import { logger } from '@rsbuild/core'

let interrupted = false
process.on('SIGINT', () => {
  if (interrupted) {
    return process.exit(/** 128 + 2(kill) */ 130)
  }

  interrupted = true
  logger.info(
    `Gracefully shutting down. Please wait... (Press Ctrl+ C again to force exit)`,
  )
})
  1. Run rsbuild dev and try exit using Ctrl+C

Expected: the log is printed and the process is not exited
Actual: the process exited

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions