diff --git a/src/common/connection.ts b/src/common/connection.ts index d55f047c..66d431f8 100644 --- a/src/common/connection.ts +++ b/src/common/connection.ts @@ -39,6 +39,7 @@ class Connection extends EventEmitter { private _availableLedgerVersions = new RangeSet() private _nextRequestID: number = 1 private _retry: number = 0 + private _connectTimer: null|NodeJS.Timer = null private _retryTimer: null|NodeJS.Timer = null private _onOpenErrorBound: null| null|((...args: any[]) => void) = null private _onUnexpectedCloseBound: null|((...args: any[]) => void) = null @@ -182,6 +183,13 @@ class Connection extends EventEmitter { } } + _clearConnectTimer() { + if (this._connectTimer !== null) { + clearTimeout(this._connectTimer) + this._connectTimer = null + } + } + _onOpen() { if (!this._ws) { return Promise.reject(new DisconnectedError()) @@ -285,9 +293,10 @@ class Connection extends EventEmitter { } connect(): Promise { + this._clearConnectTimer() this._clearReconnectTimer() return new Promise((resolve, reject) => { - const connectTimeout = setTimeout(() => { + this._connectTimer = setTimeout(() => { reject(new ConnectionError(`Error: connect() timed out after ${this._connectionTimeout} ms. ` + `If your internet connection is working, the rippled server may be blocked or inaccessible.`)) }, this._connectionTimeout) @@ -298,7 +307,7 @@ class Connection extends EventEmitter { if (this._state === WebSocket.OPEN) { resolve() } else if (this._state === WebSocket.CONNECTING) { - this._ws.once('open', resolve) + this._ws.once('open', () => resolve) } else { this._ws = this._createWebSocket() // when an error causes the connection to close, the close event @@ -319,11 +328,19 @@ class Connection extends EventEmitter { resolve, reject) this._ws.once('close', this._onUnexpectedCloseBound) this._ws.once('open', () => { - clearTimeout(connectTimeout); return this._onOpen().then(resolve, reject) }) } }) + // Once we have a resolution or rejection, clear the timeout timer as no + // longer needed. + .then(() => { + this._clearConnectTimer() + }) + .catch((err) => { + this._clearConnectTimer() + throw err; + }) } disconnect(): Promise { @@ -332,6 +349,7 @@ class Connection extends EventEmitter { _disconnect(calledByUser): Promise { if (calledByUser) { + this._clearConnectTimer() this._clearReconnectTimer() this._retry = 0 } diff --git a/test/api-test.js b/test/api-test.js index f0ee70d1..8596f620 100644 --- a/test/api-test.js +++ b/test/api-test.js @@ -153,11 +153,11 @@ describe('RippleAPI', function () { it('throws with an amount more than one decimal point', function () { assert.throws(() => { this.api.xrpToDrops('1.0.0') - }, /xrpToDrops: invalid value '1\.0\.0', should be a number matching \(\^-\?\[0-9\]\*\.\?\[0-9\]\*\$\)\./) + }, /xrpToDrops: invalid value '1\.0\.0'/) assert.throws(() => { this.api.xrpToDrops('...') - }, /xrpToDrops: invalid value '\.\.\.', should be a number matching \(\^-\?\[0-9\]\*\.\?\[0-9\]\*\$\)\./) + }, /xrpToDrops: invalid value '\.\.\.'/) }) }) @@ -267,11 +267,11 @@ describe('RippleAPI', function () { it('throws with an amount more than one decimal point', function () { assert.throws(() => { this.api.dropsToXrp('1.0.0') - }, /dropsToXrp: invalid value '1\.0\.0', should be a number matching \(\^-\?\[0-9\]\*\.\?\[0-9\]\*\$\)\./) + }, /dropsToXrp: invalid value '1\.0\.0'/) assert.throws(() => { this.api.dropsToXrp('...') - }, /dropsToXrp: invalid value '\.\.\.', should be a number matching \(\^-\?\[0-9\]\*\.\?\[0-9\]\*\$\)\./) + }, /dropsToXrp: invalid value '\.\.\.'/) }) }) @@ -3130,14 +3130,14 @@ describe('RippleAPI', function () { }); }); - it('getTransaction - ledger_index not found', function () { + it('getTransaction - transaction not validated', function () { const hash = '4FB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA11'; return this.api.getTransaction(hash).then(() => { assert(false, 'Should throw NotFoundError'); }).catch(error => { assert(error instanceof this.api.errors.NotFoundError); - assert(error.message.indexOf('ledger_index') !== -1); + assert(error.message.indexOf('Transaction has not been validated yet') !== -1); }); }); diff --git a/test/connection-test.js b/test/connection-test.js index 0ef5a6c7..6d688aa3 100644 --- a/test/connection-test.js +++ b/test/connection-test.js @@ -72,6 +72,7 @@ describe('Connection', function() { const got = data.toString('ascii', 0, expect.length); assert.strictEqual(got, expect); server.close(); + connection.disconnect(); done(); }); }); @@ -81,10 +82,10 @@ describe('Connection', function() { authorization: 'authorization', trustedCertificates: ['path/to/pem'] }; - const connection = - new utils.common.Connection(this.api.connection._url, options); - connection.connect().catch(done); - connection.connect().catch(done); + const connection = new utils.common.Connection(this.api.connection._url, options); + connection.connect().catch((err) => { + assert(err instanceof this.api.errors.NotConnectedError); + }); }, done); }); diff --git a/test/x-address-api-test.js b/test/x-address-api-test.js index 4a212bbe..98c1614e 100644 --- a/test/x-address-api-test.js +++ b/test/x-address-api-test.js @@ -2925,14 +2925,14 @@ describe('X-address Usage', function () { }); }); - it('getTransaction - ledger_index not found', function () { + it('getTransaction - transaction not validated', function () { const hash = '4FB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA11'; return this.api.getTransaction(hash).then(() => { assert(false, 'Should throw NotFoundError'); }).catch(error => { assert(error instanceof this.api.errors.NotFoundError); - assert(error.message.indexOf('ledger_index') !== -1); + assert(error.message.indexOf('Transaction has not been validated yet') !== -1); }); });