'"[Network] undefined" when trying to use subscriber - URQL

I am trying to set up a subscriber to log some output on the creation of a new Message.

Currently using Urql, with ApolloServerExpress on the backend.

I am receiving an error from the useSubscription method which I am logging to the console :

message: "[Network] undefined"
name: "CombinedError"

I know for sure my backend is working as I can subscribe using the Graphiql playground just fine. As far as front end goes, I have followed almost exactly as the example in the Urql docs.

WS Client:

const wsClient = createWSClient({
  url: "ws://localhost:4000/graphql",
});

Subscriber Exchange:

subscriptionExchange({
  forwardSubscription(operation) {
    return {
      subscribe: (sink) => {
        const dispose = wsClient.subscribe(operation, sink);
        return {
          unsubscribe: dispose,
        };
      },
    };
  },
}),

MessageList Component:

const newMessages = `
subscription Messages {
  newMessage {
    content
    status
    sender {
      id
      email
    }
    recipient {
      id
      email
    }
  }
}
`;

...

  const handleSub = (messages: any, newMessage: any) => {
    console.log("Messages: ", messages);
    console.log("newMessages: ", newMessage);
  };
  const [res] = useSubscription({ query: newMessages }, handleSub);

  console.log("Res: ", res);


Solution 1:[1]

Ended up chalking graphql-ws and switched over to subscriptions-transport-ws.

Fixed my issues.

Solution 2:[2]

I was getting the same error when using subscriptions with urql. In my case, I was able to do console.log(error.networkError); which gave a much more helpful error message than [Network] undefined. You can read more about errors in urql here.

The error I got from error.networkError was:

Event {
  "code": 4400,
  "isTrusted": false,
  "reason": "{\"server_error_msg\":\"4400: Connection initialization failed: Missing 'Authorization' or 'Cookie' header in JWT authenticati",
}

I was able to fix it by adding authentication to my subscription exchange setup. Here's the code I'm using now:

const wsClient = createWSClient({
  url: "wss://your-api-url/graphql",
  connectionParams: async () => {
    // Change this line to however you get your auth token
    const token = await getTokenFromStorage();
    return {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    };
  },
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Phil Plückthun
Solution 2 AJ Jenkins