Home > Software design >  Uncaught promise with createReadStream
Uncaught promise with createReadStream

Time:01-18

I have a basic code reading from a file, and I want to handle errors such as not being able to open the file. Here's what my code looks like:

async function processFile() {
  const fileStream = fs.createReadStream(source);

  fileStream.on('error', function(err) {
    console.log("An error occured while opening the file")
    throw err
    //return Promise.reject(err)
    //return
  });
}

async function main(){
  try{
    await processFile();
  } catch(err){
    console.error("catching error")
    return
  }
}

main()

I'm typically getting this result:

An error occured while opening the file
catching error
node:internal/process/promises:289
            triggerUncaughtException(err, true /* fromPromise */);
            ^

[Error: ENOENT: no such file or directory, open 'source.tx'] {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: 'source.tx'
}

Node.js v19.2.0

So as you can see, both custom messages are displayed properly, but I am still getting that error block, whether I'm using throw or reject()

What is the issue with the code and how can I solve it?

Thank you.

CodePudding user response:

Marking a function as async doesn't make it automatically handle errors in nested function

Create a new promise and reject the error using the reject function argument

function processFile() {
  return new Promise((resolve, reject) => {
    const fileStream = fs.createReadStream(source);

    fileStream.on("error", function (err) {
      console.log("An error occured while opening the file");
      reject(err);
    });
  });
}

async function main() {
  try {
    await processFile();
  } catch (err) {
    console.error("catching error");
    return;
  }
}

main();

CodePudding user response:

An alternative way of handling errors on streams is to use finished method.

According to doc:

A function to get notified when a stream is no longer readable, writable or has experienced an error or a premature close event.

In your case:

const { finished } = require('stream/promises');

async function processFile() {
  const fileStream = fs.createReadStream(source);
  return finished(fileStream)
}

async function main(){
  try{
    await processFile();
  } catch(err){
    console.error("catching error", err)
    return
  }
}

main()

Or if you want to have some other logic in the scope of the error(e.g. logging, ...):

async function processFile() {
  const fileStream = fs.createReadStream(source);
  return finished(fileStream).catch((error) => {
    console.log('An error occured while opening the file');
    throw error;
})
...
  • Related