saraf
saraf

Reputation: 530

reporting errors when using async with streams node.js

I am having problems trying to report errors from a function where I read a file and pipe it through csv-parse. What I want to do, is if there is a line that does not have three fields, I want to report back an error - to an async.series call. This first implementation fails as

function insertCsvIntoObject(done) {
    fs.createReadStream(inputCsvFilepath)
    .pipe(csvParser)
    .on('data', function (csvRow) {
        console.log('csv row:', csvRow);
        if (csvRow.length !== 3) {
            this.emit('error', "Does this go anywhere?");
        }
    })
    .on('end', function () {
         done(null, "Finished reading through the csv data");
     })
    .on('error', function (err) {
         console.log('errors is now:', csvReadErrors);
         done(new Error('Error reading csv file'), "CSV Parse error");
    });
}

This gives a Exception: [Error: Callback was already called.] if we have multiple problematic rows in the csv file.

Adding a return before the done

return done(new Error('Error reading csv file'), "CSV Parse error");

is also no help, since we cannot stop and return from the parent function - insertCsvIntoObject.

furthermore, if there are any error events, the .on('end',..) event never gets fired.

What is the correct way to report errors in such a situation?

Upvotes: 0

Views: 131

Answers (1)

robertklep
robertklep

Reputation: 203304

It looks like csv-parse already emits an error when the number of columns on a line isn't consistent. In other words, you shouldn't have to emit one yourself.

To prevent a callback from being called multiple times, you can use a packaged like once:

function insertCsvIntoObject(done) {
  done = once(done);
  ...
};

Ideally, you should be able to end the processing after the first error, but I haven't been able to stop the parser from parsing additional records (this.end() doesn't seem to work, but perhaps I'm missing something).

Upvotes: 1

Related Questions