2

I am using busboy to upload file in node/express app. I get error Unexpected end of multipart form and the application crash. Whenever I try the route on insomnia, nothing works. Before it was showing that Busboy is not a constructor, so I changed let to const and deleted new, leaving it as it is in the code.

What could be the cause of this error?

this is my code:

router.post('/', async (req, res) => {
    const busboy = Busboy({ headers: req.headers });
    busboy.on('finish', async () => {
        try {
            const { salaoId, servicos } = req.body;
            let error = [];
            let arquivos = [];

            console.log(req.files)

            if (req.files && Object.keys(req.files) > 0) {
                for (let key of Object.keys(req.files)) {
                    const file = req.files[key];

                    const nameParts = file.name.split('.');
                    const fileName = `${new Date().getTime()}.${nameParts[nameParts.length - 1]
                        }`;
                    const path = `servicos/${salaoId}/${fileName}`;

                    const response = await aws.uploadToS3(file, path);

                    if (response.error) {
                        error.push({ error: true, message: response.message })
                    } else {
                        arquivos.push(path)
                    }
                }
            }

            if (error.length > 0) {
                res.json(error[0]);
                return false;
            }

            //CRIAR SERVIÇO
            let jsonServico = JSON.parse(servicos);
            const servicoCadastrado = await Servicos(jsonServico).save();

            //CRIAR ARQUIVO
            arquivos = arquivos.map(arquivo => ({
                referenciaId: servicoCadastrado._id,
                model: 'Servicos',
                caminho: arquivo,
            }));

            await Arquivo.insertMany(arquivos);
            res.json({ servicos: servicoCadastrado, arquivos });

        } catch (error) {
            res.json({ error: true, message: error.message })
        }
    });
    req.pipe(req.busboy)
});

module.exports = router;

this is error:

throw er; // Unhandled 'error' event
      ^

Error: Unexpected end of form
    at Multipart._final (C:\Users\Lenovo\Desktop\projetos\meus-projetos\app-claudiagomes\ws\node_modules\busboy\lib\types\multipart.js:588:17)
6
  • Any reason you're not using Multer or express-fileupload which abstract away a lot of the complexity? Commented Dec 7, 2022 at 0:02
  • This is a ready-made project that is being taught on a youtube channel and that is why it is using busboy. No reason other than that Commented Dec 7, 2022 at 22:34
  • I would highly recommend using something easier. Multer has a lot of features but express-fileupload is easily the simplest to use. Both use BusBoy Commented Dec 7, 2022 at 22:39
  • 1
    Same problem here, and I was having the same problem with multer, which clearly did not help to solve it, so I switched to Busboy in the hope to reach the root cause Commented Jan 19, 2023 at 10:27
  • Are you using OpenApiValidator by any chance? Commented Jan 26, 2023 at 12:44

2 Answers 2

0

I had a similar problem with Next.JS API routes.
Busboy worked well using native Node.JS "http" server, as shown in example on their page, but threw an error in Next.JS. After comparing the requests in "http" server and Next.JS API route handlers I found out they are slightly different.
Difference was just in a very few properties meaning of which I didn't know, but still it gave me the idea that NextJS somehow changes the native http request, so busboy can't work with it.
I read the documentation for Next.JS and found out this

bodyParser is automatically enabled. If you want to consume the body as a Stream or with raw-body, you can set this to false.

So I added this config object, as was suggested in NextJS docs

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

and it fixed the error

Sign up to request clarification or add additional context in comments.

Comments

0

It's simple! I solved it like this

Instead of you use a BusBoy instance

const busboy = Busboy({ headers: req.headers });
busboy.on("finish", async () => {})

Use this:

req. busboy.on("finish", async () => {})

Remember that use the connect-busboy library in the index file

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.