expressjs / expressjs/multer

Error: Unexpected end of multipart data - Busboy and Dicer

Open
#961 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
JavaScript
Stars
12.1k
Forks
1.1k
Avg merge
8d 2h
Merged PRs (30d)
21

Description

I'm trying to use an endpoint node to upload a file to s3 by form-data. I'm using multer, multer-s3 and express.

Follows the function called in the controller

`async function savePerfil(req, res) {
try {

const filepath = 'monitorados'
const uploadSingle = multer(multerConfig.getUploadObj(filepath, "perfil")).single('imagem')
let file

const result2 = await new Promise((resolve, reject) => {
uploadSingle(req, res, (err) => {
if (err == 'MulterError: File too large')
reject('a imagem de perfil enviada possui tamanho acima do limite de 2Mb')
else if(err == 'filetype')
reject('a imagem de perfil enviada deve estar nos formatos: jpg, jpeg ou png')
else if(err == 'MulterError: Too many files')
reject('a requisição só aceita um arquivo por vez')
else if(err == 'Detento nao informado')
reject('o id do detento deve ser informado')
else if(err == 'MulterError: Unexpected field')
reject('o campo com a imagem deve ser informado e deve se chamar \'imagem\'')
else if(!req.file)
reject("você deve adicionar o arquivo na requisição");

file = req.file
resolve('success')
})
}).then((res) => {
return res
}).catch((err) => {
return err
})

console.log('result2 ' + result2)
if(result2 != 'success')
return res.status(400).json({status : 'Error', message : result2})

const filename = file.key
const { id_detento } = req.body

const arr = filename.split('.')
if(arr[0] == '' || arr[1] == '' || arr.length != 2)
return res.status(400).json({status : 'Error', message : "Parâmetros inválidos: o nome do arquivo deve ser no formato 'nome'.'extensão'"})

const result = await serviceDetento.updateProfileImage(id_detento, filename)

if(result == -1)
return res.status(500).json({status : 'Error', message : 'Erro ao salvar no banco.'})
else if(result == 1)
return res.status(200).json({status : 'Success', message : 'Foto de perfil salva com sucesso.'})

} catch (ex) {
console.log('catch final')
}
}`

And my multer configuration file:

`const multer = require('multer')
const path = require('path');
const crypto = require('crypto');
const multerS3 = require('multer-s3')
const { s3, bucketRel } = require('../config/s3');

const limits = {
fileSize: 2 * 1024 * 1024,
files: 1
}

function checkFileType(file, cb){
try {
const filetypes = /jpeg|jpg|png/;
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = filetypes.test(file.mimetype);

if(mimetype && extname){
cb(null, true);
} else {
cb("filetype");
}
} catch (err) {
console.log('catch 3 ' + err)
}
}

function getStorageObj(filepath, tipo, storage) {
try {


if(storage == 'local') {
return multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './tmp/uploads')
},
filename: function(req, file, cb) {
crypto.randomBytes(16, (err, hash) => {
if (err) {
cb(err)
};

file.key = `${hash.toString('hex')}-${file.originalname}`
cb(null, file.key)
})
}
})
}
else if(storage == 's3') {

return multerS3({
s3: s3,
bucket: bucketRel,
contentType: multerS3.AUTO_CONTENT_TYPE,
key: function(req, file, cb) {
const { id_detento } = req.body

if(id_detento == undefined) {
cb('Detento nao informado')
}
crypto.randomBytes(16, (err, hash) => {
if (err) {
cb(err)
};
let filename
if(tipo == "anexo")
fileName = `${filepath}/${id_detento}/${hash.toString('hex')}.${file.originalname.split('.').pop()}`
else
fileName = `${filepath}/${hash.toString('hex')}.${file.originalname.split('.').pop()}`

cb(null, fileName)
})
}
})


}
} catch (err) {
console.log('catch 2 ' + err)
}
}

function getUploadObj(destination, tipo) {
try {
return {
storage : getStorageObj(destination, tipo,'s3'),
limits : limits,
fileFilter: function(req, file, cb){
checkFileType(file, cb);
}
}
} catch (err) {
console.log('catch 1 ' + err)
}
}

module.exports = {
getUploadObj
}`

I am occasionally getting this exception, although I am doing the appropriate handling on the controller (I think). can anybody help me?

The error:

`events.js:291
throw er; // Unhandled 'error' event
^

Error: Unexpected end of multipart data
at /mnt/c/Users/emanu/Documents/Show/ApiNode/node_modules/dicer/lib/Dicer.js:62:28
at processTicksAndRejections (internal/process/task_queues.js:79:11)
Emitted 'error' event on Busboy instance at:
at Busboy.emit (/mnt/c/Users/emanu/Documents/Show/ApiNode/node_modules/busboy/lib/main.js:38:33)
at Dicer. (/mnt/c/Users/emanu/Documents/Show/ApiNode/node_modules/busboy/lib/types/multipart.js:281:9)
at Dicer.emit (events.js:314:20)
at Dicer.EventEmitter.emit (domain.js:483:12)
at Dicer.emit (/mnt/c/Users/emanu/Documents/Show/ApiNode/node_modules/dicer/lib/Dicer.js:80:35)
at /mnt/c/Users/emanu/Documents/Show/ApiNode/node_modules/dicer/lib/Dicer.js:62:14
at processTicksAndRejections (internal/process/task_queues.js:79:11)
[nodemon] app crashed - waiting for file changes before starting...`

Contributor guide

Open the contributing guide

Research direction

Start with the controller's uploadSingle call and the multer configuration's getStorageObj and getUploadObj functions. Reproduce the multipart upload failure, trace how the Busboy/Dicer error reaches the request, and compare it with the documented Multer error callback behavior. Done means the intermittent failure is explained and the request no longer crashes the process.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.