busboy on field and on file not firing
Asked Answered
S

1

5

It worked yesterday, and now it stopped without any changes made to the code. What is going on?

Client

async function uploadFile(file) {
    let formData = new FormData();

    formData.append("recordUid", recordUid);
    formData.append("fieldUid", fieldUid);
    formData.append("file", file);

    await fetchPostFormData("/api/files", formData);
}

async function fetchPostFormData(url, formData) {);
    try {
        let result = await (
            await fetch(url, {
                method: "POST",
                withCredentials: true,
                credentials: "include",
                headers: {
                    Authorization: localStorage.getItem("token"),
                },
                body: formData,
            })
        ).json();

        return result;
    } catch (err) {
        return err;
    }
}

Server

router.post("/api/files", async (req, res, next) => {
    try {
        console.log("starting upload..."); // <------------------- THIS ONE IS LOGGED

        let bb = busboy({
            headers: req.headers,
            limits: {
                fileSize: 20 * 1024 * 1024, // 20 mb
            },
        });

        let fields = {};

        // Get any text values
        bb.on("field", (fieldname, val, fieldnameTruncated, valTruncated) => {

            console.log("on.field", fieldname, val); // <------------------ NOT FIRING

            fields[fieldname] = val;
        });

        bb.on("file", (fieldname, file, filename, encoding, mimetype) => {

            console.log("on.file"); // <----------------------------------- NOT FIRING

            let parts = filename.filename.split(".");
            let name = parts[0];
            let extension = parts[parts.length - 1];

            let finalName = `${+new Date()}-${name}.${extension}`;
            let filePath = `${filesFolderPath}${finalName}`;

            // Open writeable stream to path
            let writeStream = fs.createWriteStream(filePath);

            // Pipe the file to the opened stream
            file.pipe(writeStream);

            // Check for errors
            writeStream.on("error", (err) => {
                console.log(err);
            });

            writeStream.on("close", async (err) => {
                let sizeBytes = fs.statSync(filePath).size;
            });
        });

        bb.on("finish", () => {
            res.status(200).send({ success: true });
        });
    } catch (err) {
        next(err);
    }
});
Selfcontained answered 3/2, 2022 at 20:26 Comment(2)
Any errors or warnings you can see?Coupon
Nothing. It just logs starting upload... and that's it. It's like it's not even getting to the other code. Even if there were errors, it would still log the other stuff. I had the same thing happen with Multer, which uses busboy under the hood. It's driving me insane, it makes no sense as it was working previously.Selfcontained
S
8

Managed to solve it.

The problem was the missing req.pipe(bb) at the very end.

        // previous code... ^^^^^

        bb.on("finish", () => {
            res.status(200).send({ success: true });
        });

        req.pipe(bb)  // <------------- THIS SHIT RIGHT HERE

    } catch (err) {
        next(err);
    }
});
Selfcontained answered 3/2, 2022 at 21:31 Comment(1)
Thanks @Ivan. Previously I had bb.end(req.rawBody) and was working. But lately it broken (probably version upgrades I guess).. Now with this new signature req.pipe(bb) it worked like a charm!! Thanks.Topple

© 2022 - 2024 — McMap. All rights reserved.