profusion / apollo-federation-file-upload

Add file upload support to Apollo Federated services.
32 stars 27 forks source link

Unable to upload files more than 1 Mb #32

Closed sickfar closed 3 years ago

sickfar commented 3 years ago

Hi, guys.

I'm using this library for file uploads. However, I cannot upload any file bigger than 1 Mb.

When I try to upload a bigger file, I always get response error

0: "Error: Cannot return null for non-nullable field Mutation.updateAvatar."
1: "    at completeValue (/usr/src/app/node_modules/graphql/execution/execute.js:559:13)"
2: "    at resolveField (/usr/src/app/node_modules/graphql/execution/execute.js:472:19)"
3: "    at /usr/src/app/node_modules/graphql/execution/execute.js:261:18"
4: "    at /usr/src/app/node_modules/graphql/jsutils/promiseReduce.js:23:10"
5: "    at Array.reduce (<anonymous>)"
6: "    at promiseReduce (/usr/src/app/node_modules/graphql/jsutils/promiseReduce.js:20:17)"
7: "    at executeFieldsSerially (/usr/src/app/node_modules/graphql/execution/execute.js:258:37)"
8: "    at executeOperation (/usr/src/app/node_modules/graphql/execution/execute.js:236:55)"
9: "    at executeImpl (/usr/src/app/node_modules/graphql/execution/execute.js:116:14)"
10: "    at Object.execute (/usr/src/app/node_modules/graphql/execution/execute.js:60:35)"

however, nothing logged on server side or there is no more extra information.

Sometimes (randomly and quite rarely) I get also this

0: "FetchError: request to http://uclass-accounts/graphql failed, reason: write EPIPE"
1: "    at ClientRequest.<anonymous> (/usr/src/app/node_modules/node-fetch/lib/index.js:1461:11)"
2: "    at ClientRequest.emit (events.js:387:35)"
3: "    at ClientRequest.emit (domain.js:470:12)"
4: "    at Socket.socketErrorListener (_http_client.js:475:9)"
5: "    at Socket.emit (events.js:375:28)"
6: "    at Socket.emit (domain.js:470:12)"
7: "    at emitErrorNT (internal/streams/destroy.js:106:8)"
8: "    at emitErrorCloseNT (internal/streams/destroy.js:74:3)"
9: "    at processTicksAndRejections (internal/process/task_queues.js:82:21)"

The code is quite trivial (almost the same as in Apollo doc)

class UserAgentUploadingDataSource extends FileUploadDataSource {
  willSendRequest({request, context}) {
    request.http.headers.set('User-Agent', 'uclass-gateway');
    if (context.encoded) {
      request.http.headers.set('X-UClass-User-Info', context.encoded);
    }
  }
}

const app = express()

const corsOptions = {...} as cors.CorsOptions;

app.use(cors(corsOptions))

app.use('/auth', createProxyMiddleware({ ... }));

app.use('/health', (_req, res) => {
  res.send('{"status": "UP"}')
})

app.use(graphqlUploadExpress());

async function tryCreateAndStartGateway() {
  const gateway = new ApolloGateway({
    serviceList: [ ... ],
    buildService(definition: ServiceEndpointDefinition): GraphQLDataSource {
      return new UserAgentUploadingDataSource({url: definition.url});
    },
  });

  const server = new ApolloServer({
    gateway,
    context: async ({req}) => {
//some context function
    },
  });

  await server.start()
  server.applyMiddleware({app});

  app.listen({port: PORT, host: HOST}, () =>
    console.log(`Server ready at http://${HOST}:${PORT}${server.graphqlPath}`)
  )
}

When I'm trying to debug my microservice, it does not even receive a request from the gateway.

I updated to Apollo 3, but had the same issue with 2 version. Point me to the right direction please.

cabelitos commented 3 years ago

@sickfar sorry for the delay. I'm on vacation. I looked at your backtrace and the problem does not seen related to this package (at least based on what it was posted in here).

The error that you're seeing is that you're returning null for a field that is not supposed to be null.

How is your resolver?

sickfar commented 3 years ago

I have debugged my microservice at its graphql endpoint, and figured out that it does not even receive the request (however with files less than 1mb it does). The request fails somewhere on gateway side

cabelitos commented 3 years ago

Did you try to tweak the graphql-upload options? https://github.com/jaydenseric/graphql-upload#type-processrequestoptions

Check that the maxFieldSize is exactly 1 mb by default.

sickfar commented 3 years ago

I tried tweaking other two fields, but not this. Probably browser's graphql-request (not even apollo) package sends some invalid multipart request with invalid placement of a file inside a form-field.

Thank you for the direction, I will take a look into it a bit later.

cabelitos commented 3 years ago

@sickfar any news?

sickfar commented 3 years ago

@cabelitos my turn to have a vacation :) anyway, I've checked client as well as other parts and did not find any misconfiguration or smth. So I decided to switch to direct Google Cloud storage upload, as I deploy to GCP anyway. This problem was not solved for me, but it is not actual anymore, so I close the issue