fastify-multipart icon indicating copy to clipboard operation
fastify-multipart copied to clipboard

setting onFile callback makes field._buf === null

Open timfrans opened this issue 3 years ago • 4 comments

Prerequisites

  • [X] I have written a descriptive issue title
  • [X] I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.0.1

Plugin version

7.1.0

Node.js version

16.14.2

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

12.2

Description

I defined fastify-multipart on a route this way:

const onFile = async (part: Multipart) => {
  const url = new Promise<string>((res, rej) => {
    const uploadStream = cloudinary.v2.uploader.upload_stream(
      {},
      (uploadErr, uploadResult) => {
        if (uploadErr || !uploadResult) return rej(uploadErr);

        res(uploadResult.url);
      }
    );
    const result = pipeline(part.file, uploadStream, (err) => {
      if (err) return rej(err);
    });
  });
};


server.register(async (multipartServer) => {
  multipartServer.register(multipart, {
    attachFieldsToBody: "keyValues",
    onFile,
  });

  multipartServer.post("", { schema: ... }, ...);
});

when sending a request to the post endpoint i get the following error: Cannot read properties of null (reading 'toString')

Steps to Reproduce

When configuring the fastify-multipart plugin this error is thrown when attachFieldsToBody is set to keyValues and the onFile callback is set.

Expected Behavior

The reason this error occurs is because when attaching fields to the request body there is only a check whether field._buffer !== undefined. null is logged when logging the value of field._buffer.

timfrans avatar Jul 16 '22 22:07 timfrans

Thanks for reporting!

Can you provide steps to reproduce? We often need a reproducible example, e.g. some code that allows someone else to recreate your problem by just copying and pasting it. If it involves more than a couple of different file, create a new repository on GitHub and add a link to that.

mcollina avatar Jul 18 '22 11:07 mcollina

I can create a reproducible example in a few hours.

timfrans avatar Jul 18 '22 11:07 timfrans

Here is reproducible example:

const fastifyMultipart = require("@fastify/multipart");
const fastify = require("fastify");
const { createWriteStream } = require("fs");
const { pipeline } = require("stream/promises");

const server = fastify();

const onFile = async (part) => {
  await pipeline(part.file, createWriteStream(part.filename));
};

server.register(fastifyMultipart, { attachFieldsToBody: "keyValues", onFile });

server.post(
  "/",
  {
    schema: {
      response: {
        200: {
          type: "object",
          properties: {
            result: { type: "string" },
          },
        },
      },
    },
  },
  async (req, res) => {
    return res.status(200).send({ result: "ok" });
  }
);

server.listen({ port: 3000 }, (err, address) => {
  console.log("server listening on " + address);
});
curl -v -F key1=value1 -F upload=@[filepath] http://localhost:3000/

And these are my dependencies:

"dependencies": {
    "@fastify/multipart": "7.1.0",
    "fastify": "4.2.1"
  }

timfrans avatar Jul 18 '22 17:07 timfrans

I've tried running your code with

curl -v -F key1=value1 -F upload=README.md http://localhost:3000

and I don't get any errors.

mcollina avatar Jul 22 '22 10:07 mcollina