apollographql / apollo-server

🌍  Spec-compliant and production ready JavaScript GraphQL server that lets you develop in a schema-first way. Built for Express, Connect, Hapi, Koa, and more.
https://www.apollographql.com/docs/apollo-server/
MIT License
13.79k stars 2.03k forks source link

Micro CORS sandbox "Cannot set headers after they are sent to the client" #5513

Closed RamonDonnell closed 3 years ago

RamonDonnell commented 3 years ago

Trying upgrade AS2 to AS3 using vercel serverless functions and apollo-server-micro. Sandbox doesn't connect to localhost server.

To Reproduce:

//sandbox alert
Network error: unable to reach server
We couldn't reach your server.

    The server's response may be missing CORS headers.

    To verify, please open Developer Tools and check the console for any CORS related error messages, like “Cross Origin Request Blocked”.

    If that is the case, contact your system administrator and add https://studio.apollographql.com to your server's allow-list.

    Learn more about enabling CORS 

The server may be not reachable at the provided endpoint. Please double check your configured endpoint URL for typos.Check the endpoint URL
Is the server currently running?

//server log
micro: Accepting connections on port 3000
(node:43266) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:558:11)
    at send (/Users/ramondonnell/devel/source/learn/graphql/apolloserver3/node_modules/micro/lib/index.js:76:6)
    at sendError (/Users/ramondonnell/devel/source/learn/graphql/apolloserver3/node_modules/micro/lib/index.js:83:2)
    at /Users/ramondonnell/devel/source/learn/graphql/apolloserver3/node_modules/micro/lib/index.js:110:17
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:43266) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:43266) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Note local curl query works

curl --request POST --header 'content-type: application/json' --url http://localhost:3000/graphql --data '{"query":"query { __typename }"}'
glasser commented 3 years ago

Can reproduce by replacing POST with OPTIONS in your URL line.

glasser commented 3 years ago

Looks like this is just how micro-cors works; the README should suggest actually sending a response instead of res.end(), I guess. Will fix.

Note that even after this is fixed, there's something a bit confusing in how the default graphql path is /graphql but (unlike all the other web server integrations) apollo-server-micro ignores the path for deciding whether to serve the landing page... but then the landing page lets you go to a sandbox that won't actually work because it's not on the right path. Should clean that up.

RamonDonnell commented 3 years ago

Can reproduce by replacing POST with OPTIONS in your URL line.

Yes, reproduces the same error.

curl --request OPTIONS --url http://localhost:3000/graphql