diff --git a/src/common/connection.ts b/src/common/connection.ts index 009ced86..e2cb5913 100644 --- a/src/common/connection.ts +++ b/src/common/connection.ts @@ -475,13 +475,17 @@ class Connection extends EventEmitter { _send(message: string): Promise { this._trace('send', message) return new Promise((resolve, reject) => { - this._ws.send(message, undefined, error => { - if (error) { - reject(new DisconnectedError(error.message, error)) - } else { - resolve() - } - }) + try { + this._ws.send(message, undefined, error => { + if (error) { + reject(new DisconnectedError(error.message, error)) + } else { + resolve() + } + }) + } catch (error) { + reject(new DisconnectedError(error.message, error)) + } }) } diff --git a/test/connection-test.ts b/test/connection-test.ts index 88428f56..32956476 100644 --- a/test/connection-test.ts +++ b/test/connection-test.ts @@ -201,6 +201,30 @@ describe('Connection', function() { }) }) + it('DisconnectedError on initial _onOpen send', async function() { + // _onOpen previously could throw PromiseRejectionHandledWarning: Promise rejection was handled asynchronously + // do not rely on the api.setup hook to test this as it bypasses the case, disconnect api connection first + await this.api.disconnect(); + + // stub _onOpen to only run logic relevant to test case + this.api.connection._onOpen = () => { + // overload websocket send on open when _ws exists + this.api.connection._ws.send = function(data, options, cb) { + // recent ws throws this error instead of calling back + throw new Error('WebSocket is not open: readyState 0 (CONNECTING)'); + } + const request = {command: 'subscribe', streams: ['ledger']}; + return this.api.connection.request(request); + } + + try { + await this.api.connect(); + } catch (error) { + assert(error instanceof this.api.errors.DisconnectedError); + assert.strictEqual(error.message, 'WebSocket is not open: readyState 0 (CONNECTING)'); + } + }); + it('ResponseFormatError', function() { this.api.connection._send = function(message) { const parsed = JSON.parse(message)