superagent icon indicating copy to clipboard operation
superagent copied to clipboard

Posting multipart/form-data

Open Schwartz10 opened this issue 5 years ago • 4 comments

Hi, I'm trying to test a route that accepts multipart/form-data. The route works via postman, a node script, and in the browser, but I can't seem to get it to work with supertest (who referred me to the superagent docs).

Here's the code that's working in a simple node script:

  const form = new FormData()
  form.append('entry', fs.createReadStream('./readme.md'))
  await axios.post('http://localhost:3001/api/v0/files/add', form, {
    headers: form.getHeaders()
  })
 // success!

I've tried numerous different strategies with forming a post via supertest:

test('POST file', done => {
  const form = new FormData()
  form.append('entry', fs.createReadStream('./readme.md'))
  request(app)
    .post('/api/v0/files/add')
    .type('form')
    .attach('entry', form)
    .set(form.getHeaders())
    .expect(201, done)
})

I've also tried the above with different variations, like removing .type or .set(headers), still with no luck.

The error seems to be throwing from the busboy lib, which is likely due to the multer lib:

Unhandled error. (Error: Part terminated early due to unexpected end of multipart data
      at node_modules/busboy/node_modules/dicer/lib/Dicer.js:65:36
      at processTicksAndRejections (internal/process/task_queues.js:75:11))Error [ERR_UNHANDLED_ERROR]: Unhandled error. (Error: Part terminated early due to unexpected end of multipart data
      at node_modules/busboy/node_modules/dicer/lib/Dicer.js:65:36
      at processTicksAndRejections (internal/process/task_queues.js:75:11))
      at PartStream.<anonymous> (node_modules/busboy/lib/types/multipart.js:278:17)
      at node_modules/busboy/node_modules/dicer/lib/Dicer.js:65:22

Here's the issue with supertest lib

any ideas what i'm doing wrong? Thanks for any help!

Schwartz10 avatar Oct 14 '19 02:10 Schwartz10

@Schwartz10 were you able to get this working? I would love to figure something like this out in my project, but cannot get .attach to work as I expect

danny-does-stuff avatar Feb 04 '20 19:02 danny-does-stuff

I'm having the same issue. Sometimes it works, sometimes I get ECONNRESET and sometimes I get ECONNABORTED. It could be related to #747

MRVDH avatar Jul 14 '21 11:07 MRVDH

It may be related to this issue as well https://github.com/visionmedia/superagent/issues/1607

danny-does-stuff avatar Jul 14 '21 22:07 danny-does-stuff

not sure if this is still actual, but anyway I managed to resolve it by creating the file in the server file system, then passing the path to the attach method

const uniqueDir = crypto.randomUUID();
fs.mkdirSync(`/tmp/todownload/${uniqueDir}`);
const localPath = `/tmp/todownload/${uniqueDir}/test.pdf`;
fs.writeFileSync(localPath, Buffer.from('Test pdf file data'), 'binary');

const response = await supertest(app)
      .post('/testingRoute')
      .field('field1', '{ "someProp": "Test" }')
      .field('field2', 'null')
      .attach('file', localPath);

After this multer accepted the file and I could test my code.

denisbilchenko avatar May 17 '23 15:05 denisbilchenko