bun icon indicating copy to clipboard operation
bun copied to clipboard

Node.js process.on compatibility

Open borkdude opened this issue 2 years ago • 4 comments

Repro:

process.on(
  "unhandledRejection",
  (err) => {
    console.log('error' + err);
  });

const foo = new Promise((resolve,reject) => {
  setTimeout(() => {
    reject('foo');
  }, 300);
});

Error:

$ bun run /tmp/process.js
[1.16ms] "node_modules.bun" - 105 modules, 46 packages
1 | process.on("unhandledRejection", (err) => {
  console.log("error" + err);
});
   ^
 TypeError: process.on is not a function. (In 'process.on("unhandledRejection", (err) => {
  console.log("error" + err);
})', 'process.on' is undefined)
      at /private/tmp/process.js:1:0

borkdude avatar Jul 08 '22 10:07 borkdude

hello sir, I want to work on this issue. Can you please guide me to where I can find this code inside the project?

Shubhcs01 avatar Jul 16 '22 15:07 Shubhcs01

Small update

process.on technically works but it does not monitor the events as expected, it just extends from EventEmitter. I am keeping this issue open because that doesn't fully address the intended issue

Jarred-Sumner avatar Oct 16 '22 02:10 Jarred-Sumner

Thanks! At least nbb doesn't trip over that anymore: https://twitter.com/borkdude/status/1581582447661449216

The remaining issues in nbb to have a REPL are "readline" and "vm" support.

borkdude avatar Oct 16 '22 10:10 borkdude

I'm interested in gracefully handling process exit. Right now, I noticed that some SQLite data fails to persist unless the database is gracefully closed. I'd like to do something like this:

process.on('beforeExit', () => db.close());

The SQL behavior probably warrants its own top-level issue, I suppose.

chrisdavies avatar Oct 21 '22 15:10 chrisdavies

This feature is much needed; any progress on this?

dror-weiss avatar Jul 01 '23 11:07 dror-weiss

Would really love if this got implemented!

W2Wizard avatar Jul 11 '23 09:07 W2Wizard

I'm interested in gracefully handling process exit. Right now, I noticed that some SQLite data fails to persist unless the database is gracefully closed. I'd like to do something like this:

process.on('beforeExit', () => db.close());

The SQL behavior probably warrants its own top-level issue, I suppose.

This has been fixed in canary (and will land in Bun v0.6.14)

Jarred-Sumner avatar Jul 11 '23 09:07 Jarred-Sumner

beforeExit, exit have both landed in canary as well and tomorrow signal handlers will too.

unhandledRejection will not land in this canary

Jarred-Sumner avatar Jul 11 '23 09:07 Jarred-Sumner

Hello,

// @ts-ignore
process.on('beforeExit', () => console.log('beforeExit'));
// @ts-ignore
process.on('exit', () => console.log('exit'));

// without ts-ignore, we get "Property 'on' does not exist on type 'Process'.ts(2339)"

None of them are called in 0.7.0 after pressing CTRL+C, is that expected?

baptistecs avatar Jul 26 '23 22:07 baptistecs

None of them are called in 0.7.0 after pressing CTRL+C, is that expected?

Yes, that is consistent with Node.js:

image

Jarred-Sumner avatar Jul 26 '23 22:07 Jarred-Sumner

@baptistecs normally CTRL+C is intercepted by your terminal tty driver and it usually sends an interrupt signal (SIGINT). You could do something like:

process.on('SIGINT', ...);

I often use it for closing a database connection when exiting the sever process like so (as in the better-sqlite3 docs):

process.on('exit', () => db.close());
process.on('SIGHUP', () => process.exit(128 + 1)); // hang up
process.on('SIGINT', () => process.exit(128 + 2)); // ctrl+c
process.on('SIGTERM', () => process.exit(128 + 15)); // kill

Although I'm not sure it works in bun yet. The process.on() handlers should get called, so see if it works for you.

maxmilton avatar Jul 27 '23 00:07 maxmilton

Thank you @maxmilton!

I confirm, this is working:

process.on("SIGINT", () => {
    console.log('EXIT');
    process.exit(0);
});

baptistecs avatar Jul 27 '23 01:07 baptistecs

Unfortunately, this will not be fixed by bun.js is not suitable for large projects, because without these signals it is impossible to make a normal error handler 😔

Please add unhandledRejection and uncaughtException I'll be waiting. Until then, I will use Bun only as a package manager.

DeniroBlack avatar Jan 06 '24 16:01 DeniroBlack

Same issue here. Example:

process.on('uncaughtException', function(err){
  console.log("caught2")   
})

try {
 setTimeout(() => {
  throw new Error("error")
 }, 1000)
 await new Promise((resolve) => setTimeout(resolve, 3000))
 console.log("done")
} catch(e) {
 console.log("caught")
}

Throws error on Bun, prints caught2 on node.

leona avatar Jan 31 '24 04:01 leona

Multiple event/signal handlers are missing for WinOS.

// t-events-signals.js
// ...works in NodeJS...

// Signal events
[`SIGBREAK`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `SIGTERM`].forEach((eventType) => {
	process.on(eventType, catchSignal.bind(null, eventType));
});
// IPC events
[`disconnect`, `message`].forEach((eventType) => {
	process.on(eventType, catchEvent.bind(null, eventType));
});
// Process exceptions and promise rejection events
[`uncaughtException`, `unhandledRejection`, `rejectionHandled`, `warning`].forEach((eventType) => {
	process.on(eventType, catchEvent.bind(null, eventType));
});
// Process exit events
[`beforeExit`, `exit`].forEach((eventType) => {
	process.on(eventType, catchExit.bind(null, eventType));
});
// Process worker event
[`worker`].forEach((eventType) => {
	process.on(eventType, (exitCode) => catchEvent.bind(null, eventType)(exitCode));
});

function catchSignal(eventType) {
	// upon a SIGINT, parent/shell may display a '^C'
	// * use an initial '\r' to reset line position, allowing overwrite of any initial '^C'
	console.log('\r' + 'Caught signal...', { eventType });
}
function catchEvent(eventType) {
	console.log('Caught event...', { eventType });
}
function catchExit(eventType, exitCode) {
	console.log('Now exiting...', { eventType }, { exitCode });
}

// emit unhandledRejection
const _foo = new Promise((_resolve, reject) => {
	setTimeout(() => {
		reject('foo');
	}, 300);
});

// emit uncaughtException
setTimeout(() => {
	throw ('bar');
}, 500);

setTimeout(() => {
	console.log('The service is now finished.');
}, 2000);

Note that NodeJS catches all SIGBREAKS and SIGINTS and the uncaught/unhandled errors, ending with an exit code of 0.

> node "t-events-signals.js"
Caught event... { eventType: 'unhandledRejection' }
Caught event... { eventType: 'uncaughtException' }
Caught signal... { eventType: 'SIGINT' }
Caught signal... { eventType: 'SIGINT' }
Caught signal... { eventType: 'SIGBREAK' }
Caught signal... { eventType: 'SIGBREAK' }
Caught signal... { eventType: 'SIGBREAK' }
Caught signal... { eventType: 'SIGBREAK' }
Caught signal... { eventType: 'SIGINT' }
The service is now finished.
Now exiting... { eventType: 'beforeExit' } { exitCode: 0 }
Now exiting... { eventType: 'exit' } { exitCode: 0 }

bun exits with errors and only catches the beforeExit and exit events and ends with a 1 error exit code.

> bun run "t-events-signals.js"
error: foo
Now exiting... {
  eventType: "beforeExit",
} {
  exitCode: 0,
}
Now exiting... {
  eventType: "exit",
} {
  exitCode: 1,
}
``

rivy avatar Feb 04 '24 15:02 rivy

bun --watch just logs all throws, I wonder if it is possible to implement a similar interception of throws by a listener. Such a badly needed feature.

pvlvld avatar Feb 19 '24 20:02 pvlvld

+1, I need this feature for my discord bot shard to not restart on every uncaught thrown exception

SiebeBaree avatar Mar 18 '24 17:03 SiebeBaree

+1 for the reason above

11xdeveloper avatar Mar 21 '24 18:03 11xdeveloper

+1 because alongside with this issue https://github.com/oven-sh/bun/issues/9629 these features are very needed.

supfiger avatar Mar 26 '24 01:03 supfiger

+1 for I'm going to write a game server based on bun. I need to log uncaught exceptions

dunadain avatar Mar 29 '24 08:03 dunadain

+1

Exitium-DEV avatar Mar 29 '24 22:03 Exitium-DEV

we'll add this a little after bun v1.1

Jarred-Sumner avatar Mar 31 '24 05:03 Jarred-Sumner

This will be shipped in Bun v1.1.8, which releases in a couple hours from this comment.

To get it now:

bun upgrade --canary

Jarred-Sumner avatar May 09 '24 03:05 Jarred-Sumner

Thanks for the improvements! Most of the signals are now being caught. For WinOS, 'SIGBREAK' is still being missed and causing process exceptions/panics.

rivy avatar May 09 '24 04:05 rivy