diff --git a/src/common/connection.js b/src/common/connection.js index cf1e30ef..45722703 100644 --- a/src/common/connection.js +++ b/src/common/connection.js @@ -4,7 +4,7 @@ const WebSocket = require('ws'); const parseURL = require('url').parse; const RangeSet = require('./rangeset').RangeSet; const {RippledError, DisconnectedError, NotConnectedError, - TimeoutError, ResponseFormatError} = require('./errors'); + TimeoutError, ResponseFormatError, ConnectionError} = require('./errors'); function isStreamMessageType(type) { return type === 'ledgerClosed' || @@ -115,6 +115,10 @@ class Connection extends EventEmitter { connect() { return new Promise((resolve, reject) => { + if (!this._url) { + reject(new ConnectionError( + 'Cannot connect because no server was specified')); + } if (this._state === WebSocket.OPEN) { resolve(); } else if (this._state === WebSocket.CONNECTING) { diff --git a/src/index.js b/src/index.js index dd1ce30d..895bc846 100644 --- a/src/index.js +++ b/src/index.js @@ -76,10 +76,10 @@ class RippleAPI extends EventEmitter { constructor(options: APIOptions = {}) { common.validate.apiOptions(options); super(); + this._feeCushion = options.feeCushion || 1.2; if (options.servers !== undefined) { const servers: Array = options.servers; if (servers.length === 1) { - this._feeCushion = options.feeCushion || 1.2; this.connection = new RestrictedConnection(servers[0], options); this.connection.on('ledgerClosed', message => { this.emit('ledgerClosed', server.formatLedgerClose(message)); @@ -90,6 +90,10 @@ class RippleAPI extends EventEmitter { } else { throw new errors.RippleError('Multi-server not implemented'); } + } else { + // use null object pattern to provide better error message if user + // tries to call a method that requires a connection + this.connection = new RestrictedConnection(null, options); } } } diff --git a/src/ledger/parse/account-order.js b/src/ledger/parse/account-order.js index 008ab418..517fdeb5 100644 --- a/src/ledger/parse/account-order.js +++ b/src/ledger/parse/account-order.js @@ -34,7 +34,8 @@ function parseAccountOrder(address: string, order: Object): Object { const properties = { maker: address, sequence: order.seq, - makerExchangeRate: computeQuality(takerGetsAmount, takerPaysAmount) + makerExchangeRate: order.quality ? order.quality.toString() + : computeQuality(takerGetsAmount, takerPaysAmount) }; return {specification, properties}; diff --git a/test/api-test.js b/test/api-test.js index 5f99d0e4..aea7a162 100644 --- a/test/api-test.js +++ b/test/api-test.js @@ -884,6 +884,15 @@ describe('RippleAPI - offline', function() { }); }); + it('getServerInfo - offline', function() { + const api = new RippleAPI(); + return api.getServerInfo().then(() => { + assert(false, 'Should throw error'); + }).catch(error => { + assert(error instanceof api.errors.NotConnectedError); + }); + }); + it('computeLedgerHash', function() { const api = new RippleAPI(); const header = requests.computeLedgerHash.header; diff --git a/test/mock-rippled.js b/test/mock-rippled.js index 9fb21d69..a8109229 100644 --- a/test/mock-rippled.js +++ b/test/mock-rippled.js @@ -282,8 +282,7 @@ module.exports = function(port) { assert(false, 'Unrecognized path find request: ' + JSON.stringify(request)); } - // delay response to simulate calculation time so we can test queuing - setTimeout(() => conn.send(response), 20); + conn.send(response); }); mock.on('request_gateway_balances', function(request, conn) {