node-formidable / formidable

The most used, flexible, fast and streaming parser for multipart form data. Supports uploading to serverless environments, AWS S3, Azure, GCP or the filesystem. Used in production.
MIT License
7.05k stars 682 forks source link

MaxListenersExceededWarning: Possible EventEmitter memory leak detected #422

Closed daviscai closed 4 years ago

daviscai commented 7 years ago
(node:20128) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 field listeners added. Use emitter.setMaxListeners() to increase limit
(node:20128) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 file listeners added. Use emitter.setMaxListeners() to increase limit
(node:20128) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:20128) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 end listeners added. Use emitter.setMaxListeners() to increase limit

my code :

'use strict'

const fs = require('mz/fs')
const formidable = require('formidable')

module.exports = uploadFile

function uploadFile(opts) {
  opts = opts || {}

  const form = new formidable.IncomingForm(opts);
  form.uploadDir = opts.uploadDir ||  (os.tmpdir && os.tmpdir()) || os.tmpDir();
  fs.mkdir(form.uploadDir).then(function() {}).catch((err) => {});

  return async (ctx, next)=> {

    if(!ctx.req.get('Content-Type').includes('multipart/form-data')) return next();

    if (undefined !== ctx.req.body) return next()

    await form.parse(ctx.req.raw, function(err, fields, files) {
      if (err) throw err
      let filesObj = {};
      if(files){
          for(let f in files){
              let file = {};
              for(let k in files[f]){
                  if(['domain','size','path','name','type','hash','lastModifiedDate'].includes(k)){
                      file[k] = files[f][k];
                  }
              }
              filesObj[f] = file;
          }
      }
      ctx.req.body = fields
      ctx.req.files = filesObj
    })

    return next();
  }
}

Does anyone know why? and how to fix it ?

ratwix commented 7 years ago

I have the same issue until I wait up to " form.on('end' "

nchanged commented 7 years ago

Same issue here, is it possible to fix it?

app.post("/route", expressFormidable(), (req, res) => {

}_
xarguments commented 5 years ago

Hi, thanks for reporting. @daviscai, @nchanged (and others who encounter this) could you please give more info? When does it happen?

(node:20128) MaxListenersExceededWarning: ... 11 field listeners added. Use emitter.setMaxListeners() to increase limit

There is number "11" in the error. Perhaps it happens when sending 11 upload requests at once?

pbdm commented 5 years ago

got the same issue. perhaps it's because const form = new formidable.IncomingForm(opts) is in a closure and only call once. I think we need to init a new IncomingForm for each request.

tunnckoCore commented 4 years ago

Closing, more info and examples are always welcome.

cunha-ambisis commented 2 years ago

That is still an issue. When I do POST requests, (doesn't matter if it has files or not), that warning displays. I'm not really sure if that impacts perfomance in any way, but I have not noticed any performance impact on my API. _

WARNING MESSAGE: MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 field listeners added to [IncomingForm]. Use emitter.setMaxListeners() to increase limit (Use node --trace-warnings ... to show where the warning was created)

_

I am including formidable middleware on my express.js application like this:

const form = formidable({ multiples: true, uploadDir: path.join(_dirname, 'uploads'), }); app.use((req, , next) => { form.parse(req, (_, fields, files) => { req.fields = fields; req.files = files; next(); }); });

The only middleware I include before fomidable is CORS index.js file atached. Any ideas on why that is happening? I don't like the idea to supress this warning changing the limit. issue.txt :

GrosSacASac commented 2 years ago

@cunha-ambisis you should create a new form on each request (inside app.use) See examples

cunha-ambisis commented 2 years ago

That solved my problem, thanks. My app.use is like this now:

app.use((req, _, next) => { formidable({ multiples: true, uploadDir: path.join(_dirname, 'uploads'), }).parse(req, (, fields, files) => { req.fields = fields; req.files = files; next(); }); });

bmarianome commented 2 years ago

Creating a new instance on each request worked for me. Thanks const formidable = new Formidable({ multiples: true, keepExtensions: true }) formidable.parse(req, (error, fields, files) => { console.log(fields) })

Before i defined the instance in the constructor of a class, and it throw that error.