pillarjs / pillarjs/multiparty

how to abort reading multipart form data on parse error

Open
#144 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

good first contribution
Dominant language
JavaScript
Stars
1.3k
Forks
164
Avg merge
4h 16m
Merged PRs (30d)
4

Description

Hi,

I am using multiparty to read and parse files having a specific data layout. In the event handler of form.on('part', function(...) { }), I am calling my own internal method readFile() to read and parse the file data. It works well for success scenario, where the file content is correct. I am having problems in aborting the read/parse operation, when I encounter parse error. Basically I do not know, how to propagate the error to the middleware handler so, it can abort and send http error response back to caller.

My setup of using multiparty is as below:

/**
 * Middleware to read n parse uploaded multi-part form data 
 * for campaign creation.
 * After successful parse, sends to next layer.
 **/
var mp = require('multiparty');

module.exports = function(req, res, next) {
  console.log("File processor at work...");
  var form = new mp.Form();

  form.on('part', function(part) {
    if (!part.filename) { part.resume();}
    else { 
      part.setEncoding('utf8');
      part.on('readable', function() {
        readFile(req, res,  part); 
      });

      part.on('error', function (e) {
        console.log("Am i reached??");
        //return res.status(400).json(e);
        form.emit('error', e);
      })

    }
  });

  form.on('error', function(err) {
    console.log("Error while processing upload.", 3);
    res.status(400).json(err);
  });

  form.on('close', function() {
    console.log("Reading finished. Forwarding to next layer...");
    return next();
  });

  form.parse(req);
}

In the above snippet, 'readFile' is the function in which I read from 'part' which is a readable stream. I wrote an FSM based parser, that reads each char and accumulates relevant data structures. Whenever I find something incorrect in the received char, I want to abort the whole processing. I do not know how to stop this processing. Here is my code for readFile.

/**
 * Reads the file data from a reader stream
 **/
function readFile(req, res, reader) {
    console.log("Reading data...");
    ... 
    while ((ch = reader.read(1)) !== null) {
      req.state = req.state || READING_HDR_KEY;
      switch (req.state) {
        case READING_HDR_KEY:
          ...
          break;
        case READING_HDR_VAL:
          ...
          break;
        case READING_LINE_BREAK:
          ...
          break;
        case READING_MSISDN:
          ...
          else if (isalphabet(ch)) {
            //throw new Error('Parser error: MSISDN cannot be alphanumeric.'); 
            //process.nextTick(function() {  
              //reader.emit('error', 'Parser error. eeek');
              // ??? What to do here???
              return;
            //})
            //return res.status(400).json('Parser error: MSISDN cannot be alphanumeric.');
          }
          else { msisdn += ch; }
          break;
        case READING_COMMA_OR_SPACE:
          ...
          break;
        default:
          throw new Error("Parser Error: Unknown state encountered");
      } //EOF:switch
    } //EOF:while
  //});
}

I tried a few things such as:

  1. Throwing an exception from readFile(). It got caught by outer fn i.e. form.on('part'...), but was not helpful in aborting.
  2. Tried emitting an error event from readFile(), but same behaviour.

So, how do I decently stop processing on parse error?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the middleware example and the readFile FSM in the issue, then inspect multiparty's form, part, and request stream error-handling entry points. Reproduce a parser error during part reading and trace whether the form reaches error or close. Done means the supported abort behavior and error response path are established, with a focused regression test if a library change is needed.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nodejs
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.