jaydenseric / graphql-upload

Middleware and a scalar Upload to add support for GraphQL multipart requests (file uploads via queries and mutations) to various Node.js GraphQL servers.
https://npm.im/graphql-upload
MIT License
1.43k stars 132 forks source link

xlsx is crashed after upload but csv is fine #260

Closed JingBluestone closed 3 years ago

JingBluestone commented 3 years ago

For xlsx file, after I upload, the file size increase from 16kb to 24kb, and pop up error when I try to open it Excel cannot open the file ’xxxx.xlsx’ because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file.

For csv file, the file size does not change and csv files are able to be opened.

Anyone has any thought?

jaydenseric commented 3 years ago

Some mobile operating systems do weird things to image formats when uploading, but I haven't heard of this happening for .xlsx files. Assuming you don't have any special conditional logic in your resolvers for handling that format differently to .csv, I'm not really sure what the problem could be. Are you able to somehow inspect the source of the .xlsx file to see what is different about it?

You didn't mention where your resolvers are streaming the files to. It it were me, I would try doing a very basic upload to the local filesystem in resolvers and see if the files are correct. If you are streaming it up to a cloud storage, perhaps their SDK or processing is at fault, and not your graphql-upload setup.

An out-there idea, but maybe you have a virus on your machine modifying .xlsx files that are uploaded in the browser?

JingBluestone commented 3 years ago
const { createReadStream, filename, encoding, mimetype } = await file;

    const fileStream = createReadStream();

    const s3 = new S3({
      s3ForcePathStyle: true,
      endpoint: config.AWS_S3_ENDPOINT ?? undefined
    });
    const params = {
      Bucket: 'Bucket',
      Key: filename,
      Body: fileStream,
      ContentType: mimetype,
      ContentEncoding: encoding
    };
    await s3.upload(params).promise();

Here is my codes and I am using with apollo-server-lambda and apply the middleware like

 expressAppFromMiddleware(middleware) {
    const app = express();
    app.use(graphqlUploadExpress());
    app.use(middleware);
    return app;
  }

And I also running it among different devices, all have the same issue

jaydenseric commented 3 years ago

Note that AWS Lambda is not officially supported, see:

https://github.com/jaydenseric/graphql-upload/issues/155

Sometimes the file type is a red-herring, and the real difference that causes a bug is actually file size. Are you sure you are testing .xlsx and .csv files exactly the same size?

JingBluestone commented 3 years ago

the testing .xlsx file size is 16KB, and testing .csv file size is 8KB. After uploading, .xlsx file increased to 24KB while .csv does not change.

jaydenseric commented 3 years ago

Try uploading a 16 KB .csv file and see what happens.

JingBluestone commented 3 years ago

I just tried to upload a 27KB .csv, it is working fine. The testing 27KB .csv is coverted from the testing 16KB .xlsx file

JingBluestone commented 3 years ago

Do you have any suggestion @jaydenseric

jaydenseric commented 3 years ago

I just tested uploading a ~33 KB .xlsx file with the Apollo upload examples app and GraphQL API, and it works perfectly fine.

I'm not sure what your problem is, but there is something problematic about your particular project code, dependencies, or environment. As previously mentioned, AWS Lambda is not specifically supported by this project as it doesn't properly support streaming multipart requests.

If you want to persevere, try a process of elimination. Use the browser network inspector to make sure that the client is sending a valid GraphQL multipart request. Try using a regular Apollo Server instead of the Lambda version, etc.

Whatever you find the problem to be, share it here! I'm interested to hear the answer.

JingBluestone commented 3 years ago

I figured it out yesterday. Forgot to add multipart/form-data in Binary Media Types for api gateway. It is my fault. Thank you for your help.