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.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

formidable is stuck at parse function's callback

richard-here opened this issue · comments

Support plan

  • Which support plan is this issue covered by? (Community, Sponsor, Enterprise): Community
  • Currently blocking your project/work? (yes/no): yes
  • Affecting a production system? (yes/no): no

Context

  • Node.js version: v16.20.1
  • Release Line of Formidable (Legacy, Current, Next): Next
  • Formidable exact version: formidable@3.5.0
  • Environment (node, browser, native, OS): node
  • Used with (popular names of modules): express

What are you trying to achieve or the steps to reproduce?

I am trying to create an API endpoint that accepts uploading an Excel file in Node.js with Express and Formidable. After uploading the Excel file, I will parse the content of the file with another package to insert the parsed data to MongoDB using Mongoose. Currently, I am stuck at the parse function of Formidable.

const express = require('express')
const cors = require('cors')
const { IncomingForm } = require('formidable')

const app = express()
app.use(cors({ origin: true }))
app.use(express.json()) // Commenting this line does not make it work either

const router = express.Router()
router.post(
  '/upload',
  (req, res, next) => {
    const form = new IncomingForm({})
    console.log(form)
    form.parse(req, (err, fields, files) => {
      if (err) {
        throw err
      }
      console.log(fields)
      console.log(files)
      res.send('hi')
    })
  }
)

app.use('/', router)

module.exports = app

To call the API endpoint on Postman, here's what I did. The uploaded file is 15KB.
image
image

What was the result you got?

The request got stuck when I tried to hit that API endpoint using Postman. It does log the console.log(form) statement, but anything beyond that seems to never run.

What result did you expect?

To be able to log what fields and files contain as well as sending a hi as a response in Postman.

Just came here with the exact same use case. The callback never resolves, no error either.

Just to make it simpler without all the postman/insomnia UI:

curl --request POST \
  --url <my url> \
  --header 'Content-Type: multipart/form-data' \
  --form field1=eee \
  --form field2=text

Results in parse hanging.

Try again with node v20, and without express

@GrosSacASac just curious but... why? The docs say node > 10.13 is supported, and there is explicit express integration support in the docs.

Yes, but first of all we need to find the source of the problem.

Since it works for me (I just tested the curl example) I conclude that it must something that we have different. which is node version or express.

Once we find the source of the problem we can try to find the solution or update the docs

Face the same issue today, but it turned out I forget to disable the nextjs bodyParser.

export const config = {
  api: {
    bodyParser: false,
  },
};

I have found the main issue for my case. It wasn't because of the Node version or the Express version, but instead on which I ran my Express app: Google Cloud Functions.

It turns out that Google Cloud Functions implement some middleware that converts inputs that are files into raw data type (Buffer) in req.rawBody (full description here: https://stackoverflow.com/a/47319614). It seems that Formidable requires the data type unmodified, and as the data is automatically modified when running on an Express app on Google Cloud Functions, I concluded that my case is not the right use case to use Formidable.

At the same time, I tried running Formidable on a regular Express app and it worked with the Node version I provided in the original issue submission.

For others facing the same issue, you can instead parse the raw data using Busboy.

Next time test locally before making an issue.

Someone made https://github.com/Amit-A/formidable-serverles that uses req.rawBody. I am not sure that it is a clean solution.

related #594

Sorry to resurrect this, but shouldn't formidable throw some kind of error if it can't parse the request? Would a PR exposing the error be accepted? Could blow things up, but it's better than silent failure.