altangent / ccxws

WebSocket client for 38 cryptocurrency exchanges
MIT License
619 stars 187 forks source link

Gateio: Unexpected server response: 502 #225

Closed MidoMiddle closed 3 years ago

MidoMiddle commented 3 years ago

I have this error

Error: Unexpected server response: 502
    at ClientRequest.<anonymous> (/Users/User/Store/server/testServer/node_modules/ws/lib/websocket.js:576:7)
    at ClientRequest.emit (events.js:314:20)
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:640:27)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:119:17)
    at TLSSocket.socketOnData (_http_client.js:509:22)
    at TLSSocket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:303:12)
    at readableAddChunk (_stream_readable.js:279:9)
    at TLSSocket.Readable.push (_stream_readable.js:218:10)
    at TLSWrap.onStreamRead (internal/stream_base_commons.js:188:23)

In official example (https://github.com/gateio/WebSocket-API/tree/master/nodejs) I have this

error ErrorEvent {
  target: WebSocket {
    _events: [Object: null prototype] {
      open: [Function],
      message: [Function],
      close: [Function],
      error: [Function]
    },
    _eventsCount: 4,
    _maxListeners: undefined,
    readyState: 2,
    protocol: '',
    _binaryType: 'nodebuffer',
    _closeFrameReceived: false,
    _closeFrameSent: false,
    _closeMessage: '',
    _closeTimer: null,
    _closeCode: 1006,
    _extensions: {},
    _receiver: null,
    _sender: null,
    _socket: null,
    _bufferedAmount: 0,
    _isServer: false,
    _redirects: 0,
    url: 'wss://ws.gateio.io/v3/',
    _req: null,
    [Symbol(kCapture)]: false
  },
  type: 'error',
  message: 'certificate has expired',
  error: Error: certificate has expired
      at TLSSocket.onConnectSecure (_tls_wrap.js:1497:34)
      at TLSSocket.emit (events.js:314:20)
      at TLSSocket._finishInit (_tls_wrap.js:932:8)
      at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:706:12) {
    code: 'CERT_HAS_EXPIRED'
  }
}
close
WoutervDijk commented 3 years ago

I have the same problem. No idea what causes it though @bmancini55

WoutervDijk commented 3 years ago

I have tried downgrading to an older version, but this does not fix the issue. You can easily recreate the error by looking at any market with L2 data (i.e. subscripeLevel2Updates). Note that this problem is new and happened out of no where for me. Issue happens in Windows as well as Linux.

bmancini55 commented 3 years ago

I'm seeing this error every few connection attempts. The automatic retry usually resolves it within an attempt or two, so that seems to be working ok. Are you not able to connect at all?

502 is usually a gateway issue. From the error @MidoMiddle reported it looks like " error: Error: certificate has expired". My guess is they have a misconfigured server?

WoutervDijk commented 3 years ago

I have no idea why it is happening. It might reconnect, but the error does not get caught at all. Note this didn't happen before. Here is my full error:

events.js:292
      throw er; // Unhandled 'error' event
      ^

Error: Unexpected server response: 502
    at ClientRequest.<anonymous> (C:\Users\Wouter\IdeaProjects\Poseidon\node_modules\ws\lib\websocket.js:576:7)
    at ClientRequest.emit (events.js:315:20)
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:596:27)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:119:17)
    at TLSSocket.socketOnData (_http_client.js:469:22)
    at TLSSocket.emit (events.js:315:20)
    at addChunk (_stream_readable.js:295:12)
    at readableAddChunk (_stream_readable.js:271:9)
    at TLSSocket.Readable.push (_stream_readable.js:212:10)
    at TLSWrap.onStreamRead (internal/stream_base_commons.js:186:23)
Emitted 'error' event on GateioClient instance at:
    at GateioClient._onError (C:\Users\Wouter\IdeaProjects\Poseidon\node_modules\ccxws\src\basic-client.js:206:10)
    at SmartWss.emit (events.js:315:20)
    at WebSocket.<anonymous> (C:\Users\Wouter\IdeaProjects\Poseidon\node_modules\ccxws\src\smart-wss.js:77:41)
    at WebSocket.emit (events.js:315:20)
    at abortHandshake (C:\Users\Wouter\IdeaProjects\Poseidon\node_modules\ws\lib\websocket.js:694:15)
    at ClientRequest.<anonymous> (C:\Users\Wouter\IdeaProjects\Poseidon\node_modules\ws\lib\websocket.js:576:7)
    [... lines matching original stack trace ...]
    at TLSSocket.socketOnData (_http_client.js:469:22)
bmancini55 commented 3 years ago

Ah, you need to make sure you attach an error event handler to your client or the node process will exit (https://nodejs.org/api/events.html#events_error_events). The client should then detect the failed connection attempt and retry a socket connection.

WoutervDijk commented 3 years ago

The weird thing is that this error already happens at the start. Or almost immediately after opening the stream. I thought you mentioned there was an automatic retry? And if not where would you catch the error? Because I am not sure what event handler you are talking about.

bmancini55 commented 3 years ago

Sorry for the confusion! When you make a subscription it first tries to establish a socket connection. If everything is working, once the socket has connected, the subscription payload is sent to the server over the socket. When connecting to the remote server, it does it over HTTP. The 502 error is an HTTP error that indicates an inability to connect to the remote server. CCXWS contains logic that detects a failed socket connection attempt and will retry until it is successful. Once the connection is successful, the subscription payloads get sent over the socket.

To add an error event handler to your client you just attach the event to the clients on method:

const client = ccxws.Gateio();
client.on("error", console.error);
client.on("l2snapshot", console.log);
client.on("l2update", console.log);

const market = { id: "btc_usdt", base: "BTC", quote: "USDT", type: "spot" };
client.subscribeLevel2Updates(market);
WoutervDijk commented 3 years ago

@bmancini55 thank you for the response! There is one more thing, when this 502 error happens, does that happen only at the start or can it also happen once data has already been streaming through the socket? In case of the latter, would that result in missing L2update data and therefore result in an OrderBook that is not complete anymore?

bmancini55 commented 3 years ago

If for some reason the socket connection drops, when ccxws reconnects, you could get a 502 error when trying to reestablish the connection. You would certainly miss updates in this case because the connection has dropped.

Most exchanges will send a snapshot upon connection and then start streaming updates. Your order book code should reset its state when it receives a new snapshot to resync with the current update stream.