apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.38k stars 2.66k forks source link

on error ReferenceError: WebSocket is not defined #11761

Open arenevier opened 7 months ago

arenevier commented 7 months ago

Issue Description

I am using apollo client with GraphQLWsLink in node.

When an error happens, an exception happens during the handling of that error

Trace is

on error  ReferenceError: WebSocket is not defined
    at isLikeErrorEvent (/home/arno/project/node_modules/@apollo/client/link/subscriptions/index.js:42:111)
    at Object.error (/home/arno/project/node_modules/@apollo/client/link/subscriptions/index.js:62:38)
    at Object.<anonymous> (/home/arno/project/node_modules/graphql-ws/lib/client.js:396:38)
    at emit (/home/arno/project/node_modules/graphql-ws/lib/client.js:106:94)
    at Object.emit (/home/arno/project/node_modules/graphql-ws/lib/client.js:133:21)
    at WebSocketImpl.socket.onmessage (/home/arno/project/node_modules/graphql-ws/lib/client.js:232:29)
    at callListener (/home/arno/project/node_modules/ws/lib/event-target.js:290:14)
    at WebSocketImpl.onMessage (/home/arno/project/node_modules/ws/lib/event-target.js:209:9)
    at WebSocketImpl.emit (node:events:519:28)
    at WebSocketImpl.emit (node:domain:488:12)

This happens because of that line. WebSocket is not defined in node environment.

return isNonNullObject(err) && err.target?.readyState === WebSocket.CLOSED;

Link to Reproduction

don't have one, but the root of the issue is obvious

Reproduction Steps

No response

@apollo/client version

3.9.10

alessbell commented 7 months ago

Hi @arenevier 👋 Appreciate the bug report! What does the error event you're receiving look like? Are you using ws? A reproduction would be helpful to check our assumptions. We'd also love any PRs here :)

arenevier commented 7 months ago

any type of error will create that. For example:

[                                                                                                                       
  {                                                                                                                                      
    message: 'Cannot query field "eid" on type "IFooBar". Did you mean "_eid"?',                                       
    locations: [ [Object] ]                                                                                                              
  }                                                                                                                                      
]

Yes, I'm using ws,

    const wsLink = new GraphQLWsLink(createClient({
     url: 'wss://my-url/graphql',
      webSocketImpl: WebSocket,
      connectionParams: {
           ...
      }
    }));
alessbell commented 6 months ago

Thanks, @arenevier. You should also set that WebSocket implementation you're passing to webSocketImpl on globalThis in your node environment which I would expect to resolve the error. Can you please try that and let me know how it goes?

arenevier commented 6 months ago

Yes, that would work.

It looks like I am not the first to bump into this issue: https://github.com/apollographql/apollo-client/issues/11063

Should that be specified in the documentation?

Alternatively, replacing WebSocket.CLOSED by it's value (3) would also fix the issue for everyone.

alessbell commented 6 months ago

Yes, that should definitely be added to the docs :) I'll look at opening that PR today.