rdf-ext / rdf-parser-csvw

CSV on the Web parser
MIT License
16 stars 4 forks source link

Event processing loop is broken in case of exceptions #29

Closed luav closed 3 years ago

luav commented 3 years ago

The lack of the proper exception handling in CsvParser breaks the event loop of NodeJs, resulting in the exception that can not be handled anywhere upper in the call stack:

events.js:174
      throw er; // Unhandled 'error' event
      ^

Error: Invalid Record Length: columns length is 10, got 3 on line 42
    at Parser.__onRecord (/media/truecrypt1/projects/consulting/zazuko/csv-validate/node_modules/csv-parse/lib/index.js:783:9)
    at Parser.__parse (/media/truecrypt1/projects/consulting/zazuko/csv-validate/node_modules/csv-parse/lib/index.js:660:40)
    at Parser._transform (/media/truecrypt1/projects/consulting/zazuko/csv-validate/node_modules/csv-parse/lib/index.js:467:22)
    at Parser.Transform._read (_stream_transform.js:190:10)
    at Parser.Transform._write (_stream_transform.js:178:12)
    at doWrite (_stream_writable.js:415:12)
    at writeOrBuffer (_stream_writable.js:399:5)
    at Parser.Writable.write (_stream_writable.js:299:11)
    at CsvParser._transform (/media/truecrypt1/projects/consulting/zazuko/csv-validate/lib/CsvParser.js:65:19)
    ...

The outlined unhandled exception is not catched by both async .catch( (err) = {} ) and sync try { ... } catch (err) { }, for example in the following code:

for (const filename in filesInfo) {
        // Handle the file
        try {
          await parseFile(filename, { relaxColumnCount, skipErrorLines, delimiter, quotes, newLine, encoding }, ...
          ).catch((err) => {
            console.error(`ERROR in ${filename}: ${err}`) // err.stack
          })
        } catch (err) {
          // Note: this should never happen if CsvParser works correctly
          console.error(`ERROR SYNC in ${filename}: ${err}`)
        }
      }

Exceptions in _transform should be forwarded to its callback (see the original csv-parse code for the reference) as follows:

  _transform (chunk, encoding, callback) {
    try {
      this.parser.write(chunk, encoding, callback)
    } catch(err) {
      callback(err)
    }
  }

Then, any exceptions in _transform can be handled properly by the async .catch( (err) = {} ).

The respective test for CsvParser is available in csv-validate.

bergos commented 3 years ago

Thanks for reporting. Fixed in #30 .