Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to abort reading multipart form data on parse error #144

Open
rvnath opened this issue Aug 15, 2016 · 1 comment
Open

how to abort reading multipart form data on parse error #144

rvnath opened this issue Aug 15, 2016 · 1 comment

Comments

@rvnath
Copy link

rvnath commented Aug 15, 2016

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?

@dougwilson
Copy link
Contributor

Hi @rvnath currently there is no good way to actually stop the parsing, but I think it would be a good feature to add, if you're up for making a PR :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants