question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Does form-data support fs-capacitor stream?

See original GitHub issue

I’m using apollo-upload-server for uploading files to the server. In my resolver function, I have a stream. What I want to do is pass this stream as a file (multipart/form-data) to another server. I use promise-request (that under the hood use form-data to achieve that. Code look like below:

import * as request from 'request-promise';

async upload(_, { file }) {
  const { stream } = await file;
  return await request.post({
      uri: `${NLP_API_BASE}/upload`,
      formData: {
        datasheet: stream
      }
    });
}

But I’m getting an error : RequestError: Error: socket hang up at new RequestError (/Users/igat/Code/projects/botsupply-oracle-backend/node_modules/request-promise-core/lib/errors.js:14:15) at Request.plumbing.callback (/Users/igat/Code/projects/botsupply-oracle-backend/node_modules/request-promise-core/lib/plumbing.js:87:29) at Request.RP$callback [as _callback] (/Users/igat/Code/projects/botsupply-oracle-backend/node_modules/request-promise-core/lib/plumbing.js:46:31) at self.callback (/Users/igat/Code/projects/botsupply-oracle-backend/node_modules/request/request.js:185:22) at emitOne (events.js:121:20) at Request.emit (events.js:211:7) at Request.onRequestError (/Users/igat/Code/projects/botsupply-oracle-backend/node_modules/request/request.js:877:8) at emitOne (events.js:116:13) at ClientRequest.emit (events.js:211:7) at Socket.socketOnEnd (_http_client.js:423:9) at emitNone (events.js:111:20) at Socket.emit (events.js:208:7) at endReadableNT (_stream_readable.js:1056:12) at _combinedTickCallback (internal/process/next_tick.js:138:11) at process._tickDomainCallback (internal/process/next_tick.js:218:9)

And as I understand apollo-upload-server use fs-capacitor to deal with a stream. Does form-data support fs-capacitor stream? What is wrong with my code?

Guys any ideas? I’m really stuck.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:5
  • Comments:22

github_iconTop GitHub Comments

14reactions
amannncommented, Oct 17, 2019

@rheaditi I tested a few different approaches and ended up with this resolver for a file upload with apollo-upload-server@7.0.0.

import FormData from 'form-data';
import {GraphQLUpload} from 'apollo-upload-server';
import rawBody from 'raw-body';
import fetch from 'node-fetch';

export default {
  Upload: GraphQLUpload,

  Mutation: {
    uploadFile: (root, {file: fileUpload}) =>
      fileUpload.then(file =>
        rawBody(file.createReadStream()).then(buffer => {
          const form = new FormData();

          // `FormData` accepts either a readable stream, a buffer or a string
          // for multipart files. `file.createReadStream()` creates a
          // `FileStream`, which is a subclass of `ReadableStream` implemented
          // in `busboy` (dependency of `apollo-upload-server`). This kind of
          // stream is apparently not discovered correctly by `form-data`,
          // therefore the better option is to use a buffer, however the meta
          // data needs to be specified explicitly in this case.
          form.append('file', buffer, {
            filename: file.filename,
            contentType: file.mimetype,
            knownLength: buffer.length
          });

          // Something like this, I'm using some abstraction for this
          return fetch('/upload', {method: 'POST', body: form});
        })
      )
  }
};

Maybe this is helpful to you! I haven’t tested with newer versions of apollo-upload-server yet.

7reactions
lynxtaacommented, Jan 13, 2020

It works for me with additional headers (using node-fetch)

const { filename, createReadStream } = await file

const form = new FormData()

form.append('file', createReadStream(), { filename })

await fetch(FILE_SERVER_URL, {
  method: 'PUT',
  body: form,
  headers: {
    'connection': 'keep-alive',
    'transfer-encoding': 'chunked',
  },
})
Read more comments on GitHub >

github_iconTop Results From Across the Web

Developers - Does form-data support fs-capacitor stream? -
Does form-data support fs-capacitor stream ?
Read more >
How to pass Duplex Stream in formdata? - Stack Overflow
Image saved in s3 is downloaded as a stream and it is piped to duplex stream. The stream which is coming from s3...
Read more >
GraphQL: File Upload & Troubleshooting - Szhshp
Client is using apollo-upload-client which implemented ... Option 2: You can port the file to assets server if you need */ const formData ......
Read more >
apollo-upload-server | Yarn - Package Manager
Middleware and an Upload scalar to add support for GraphQL multipart requests (file uploads via queries and mutations) to various Node.js GraphQL servers....
Read more >
Open Source Attribution - D2iQ Docs
Vendor Name Version License Id panva asn1.js 1.0.0 MIT sindresorhus is 4.0.0 MIT szmarczak http‑timer 4.0.5 MIT
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found