1

While experimenting with readable.read() and readable.once('redable') I stumbled upon a peculiar problem. Seems like one of the abote kills my node.js process without any error.

I would expect that the following code will throw an error or will hang indefinitely

const { createReadStream } = require('fs');

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

process.on('error', e => {
  console.log('error', e)
});

process.on('exit', e => {
  console.log('exit', e)
});

(async () => {
  // test.txt is an empty file
  const stream = createReadStream('test.txt', { encoding: 'utf-8' })
  const waitForReadable = () => new Promise(r => stream.once('readable', r))
  for (let i = 0; i < 1000; i += 1) {
    console.log(i)
    stream.read()
    await waitForReadable()
  }
})()

But instead, it outputs:

0
1
exit 0
Konrad
  • 21,590
  • 4
  • 28
  • 64

1 Answers1

1

The way createReadStream behaves is that it closes the stream once it reaches the end-of-file after it fires the end event. There is no way to override this behavior as far as I could find.

autoClose seems like it might handle it, but it does not. This is the only part of the documentation that describes this behavior.

If autoClose is false, then the file descriptor won't be closed, even if there's an error. It is the application's responsibility to close it and make sure there's no file descriptor leak. If autoClose is set to true (default behavior), on 'error' or 'end' the file descriptor will be closed automatically.

Once the end event is fired and all event subscribers unsubscribe, the event-loop is cleared and Node.js terminates itself.

If you're looking to have a tail-like experience, you will need to go through fs.watchFile

Slava Knyazev
  • 5,377
  • 1
  • 22
  • 43
  • Shouldn't node.js wait for the promise to resolve even if it never will? – Konrad Jan 03 '23 at 21:54
  • @Konrad : [a relevant answer that explains this](https://stackoverflow.com/a/46916601/14357) – spender Jan 03 '23 at 21:56
  • @Konrad Event subscribers have means on short-circuiting if their event will never happen. In a contrived way, it's similar to why this program terminates instead of hanging forever: https://paste.rs/auM – Slava Knyazev Jan 03 '23 at 22:06