From 87dac759199ab0ff253aa81fff4519912f80bae8 Mon Sep 17 00:00:00 2001 From: Chris Clark Date: Tue, 27 Oct 2015 17:14:23 -0700 Subject: [PATCH] Cleanup error classes --- src/common/connection.js | 8 +- src/common/errors.js | 180 ++++++++++---------------------------- src/common/utils.js | 2 +- src/ledger/transaction.js | 4 +- test/api-test.js | 34 +------ 5 files changed, 53 insertions(+), 175 deletions(-) diff --git a/src/common/connection.js b/src/common/connection.js index 7030ccac..29296d52 100644 --- a/src/common/connection.js +++ b/src/common/connection.js @@ -4,7 +4,7 @@ const WebSocket = require('ws'); // temporary: RangeSet will be moved to api/common soon const RangeSet = require('./rangeset').RangeSet; const {RippledError, DisconnectedError, NotConnectedError, - TimeoutError, UnexpectedError} = require('./errors'); + TimeoutError, ResponseFormatError} = require('./errors'); function isStreamMessageType(type) { return type === 'ledgerClosed' || @@ -29,7 +29,7 @@ class Connection extends EventEmitter { const data = JSON.parse(message); if (data.type === 'response') { if (!(Number.isInteger(data.id) && data.id >= 0)) { - throw new UnexpectedError('valid id not found in response'); + throw new ResponseFormatError('valid id not found in response'); } return [data.id.toString(), data]; } else if (isStreamMessageType(data.type)) { @@ -43,7 +43,7 @@ class Connection extends EventEmitter { } else if (data.type === undefined && data.error) { return ['error', data.error, data.error_message]; // e.g. slowDown } - throw new UnexpectedError('unrecognized message type: ' + data.type); + throw new ResponseFormatError('unrecognized message type: ' + data.type); } _onMessage(message) { @@ -207,7 +207,7 @@ class Connection extends EventEmitter { } else if (response.status === 'success') { _resolve(response.result); } else { - _reject(new UnexpectedError( + _reject(new ResponseFormatError( 'unrecognized status: ' + response.status)); } }); diff --git a/src/common/errors.js b/src/common/errors.js index 6b9de2b3..6055983c 100644 --- a/src/common/errors.js +++ b/src/common/errors.js @@ -1,169 +1,77 @@ -/* eslint-disable valid-jsdoc */ 'use strict'; - const util = require('util'); -const utils = require('./utils'); -/** - * Base class for all errors - */ -function RippleError(message) { - this.message = message; -} - -RippleError.prototype = Object.create(Error.prototype); -RippleError.prototype.name = 'RippleError'; - - -RippleError.prototype.toString = function() { - let result = '[' + this.name + '(' + this.message; - if (this.data) { - result += ', ' + util.inspect(this.data); - } - result += ')]'; - return result; -}; - -/* - console.log in node uses util.inspect on object, and util.inspect allows - to cutomize it output: - https://nodejs.org/api/util.html#util_custom_inspect_function_on_objects -*/ -RippleError.prototype.inspect = function(depth) { - utils.unused(depth); - return this.toString(); -}; - -class RippledError extends RippleError { +class RippleError extends Error { constructor(message) { super(message); this.name = this.constructor.name; this.message = message; Error.captureStackTrace(this, this.constructor.name); } -} -class ConnectionError extends RippleError { - constructor(message) { - super(message); - this.name = this.constructor.name; - this.message = message; - Error.captureStackTrace(this, this.constructor.name); + toString() { + let result = '[' + this.name + '(' + this.message; + if (this.data) { + result += ', ' + util.inspect(this.data); + } + result += ')]'; + return result; + } + + /* console.log in node uses util.inspect on object, and util.inspect allows + us to cutomize its output: + https://nodejs.org/api/util.html#util_custom_inspect_function_on_objects */ + inspect() { + return this.toString(); } } -class NotConnectedError extends ConnectionError { +class RippledError extends RippleError {} + +class UnexpectedError extends RippleError {} + +class ConnectionError extends RippleError {} + +class NotConnectedError extends ConnectionError {} + +class DisconnectedError extends ConnectionError {} + +class TimeoutError extends ConnectionError {} + +class ResponseFormatError extends ConnectionError {} + +class ValidationError extends RippleError {} + +class NotFoundError extends RippleError { constructor(message) { - super(message); + super(message || 'Not found'); } } -class DisconnectedError extends ConnectionError { +class MissingLedgerHistoryError extends RippleError { constructor(message) { - super(message); + super(message || 'Server is missing ledger history in the specified range'); } } -class TimeoutError extends ConnectionError { +class PendingLedgerVersionError extends RippleError { constructor(message) { - super(message); + super(message || 'maxLedgerVersion is greater than server\'s' + + 'most recent validated ledger'); } } -class UnexpectedError extends ConnectionError { - constructor(message) { - super(message); - } -} - -function ValidationError(message) { - this.message = message; -} -ValidationError.prototype = new RippleError(); -ValidationError.prototype.name = 'ValidationError'; - -/** - * Timeout, disconnects and too busy - */ -function NetworkError(message) { - this.message = message; -} -NetworkError.prototype = new RippleError(); -NetworkError.prototype.name = 'NetworkError'; - -/** - * Failed transactions, no paths found, not enough balance, etc. - */ -function RippledNetworkError(message) { - this.message = message !== undefined ? message : 'Cannot connect to rippled'; -} -RippledNetworkError.prototype = new NetworkError(); - -/** - * Failed transactions, no paths found, not enough balance, etc. - */ -function TransactionError(message) { - this.message = message; -} -TransactionError.prototype = new RippleError(); -TransactionError.prototype.name = 'TransactionError'; - -/** - * Asset could not be found - */ -function NotFoundError(message) { - this.message = message; -} -NotFoundError.prototype = new RippleError(); -NotFoundError.prototype.name = 'NotFoundError'; - -function MissingLedgerHistoryError(message) { - this.message = message || - 'Server is missing ledger history in the specified range'; -} -MissingLedgerHistoryError.prototype = new RippleError(); -MissingLedgerHistoryError.prototype.name = 'MissingLedgerHistoryError'; - -function PendingLedgerVersionError(message) { - this.message = message || - 'maxLedgerVersion is greater than server\'s most recent validated ledger'; -} -PendingLedgerVersionError.prototype = new RippleError(); -PendingLedgerVersionError.prototype.name = 'PendingLedgerVersionError'; - -/** - * Request timed out - */ -function TimeOutError(message) { - this.message = message; -} -TimeOutError.prototype = new RippleError(); -TimeOutError.prototype.name = 'TimeOutError'; - -/** - * API logic failed to do what it intended - */ -function ApiError(message) { - this.message = message; -} -ApiError.prototype = new RippleError(); -ApiError.prototype.name = 'ApiError'; - module.exports = { - ValidationError, - NetworkError, - TransactionError, - RippledNetworkError, - NotFoundError, - PendingLedgerVersionError, - MissingLedgerHistoryError, - TimeOutError, - ApiError, RippleError, + UnexpectedError, ConnectionError, RippledError, NotConnectedError, DisconnectedError, TimeoutError, - UnexpectedError + ResponseFormatError, + ValidationError, + NotFoundError, + PendingLedgerVersionError, + MissingLedgerHistoryError }; diff --git a/src/common/utils.js b/src/common/utils.js index 1b91e648..6ee5e70b 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -38,7 +38,7 @@ function generateAddressAPI(options?: Object): Object { try { return generateAddress(options); } catch (error) { - throw new errors.ApiError(error.message); + throw new errors.UnexpectedError(error.message); } } diff --git a/src/ledger/transaction.js b/src/ledger/transaction.js index f6b7199b..fbd42249 100644 --- a/src/ledger/transaction.js +++ b/src/ledger/transaction.js @@ -28,9 +28,9 @@ function attachTransactionDate(connection: Connection, tx: Object if (typeof data.ledger.close_time === 'number') { return _.assign({date: data.ledger.close_time}, tx); } - throw new errors.ApiError('Ledger missing close_time'); + throw new errors.UnexpectedError('Ledger missing close_time'); }).catch(error => { - if (error instanceof errors.ApiError) { + if (error instanceof errors.UnexpectedError) { throw error; } throw new errors.NotFoundError('Transaction ledger not found'); diff --git a/test/api-test.js b/test/api-test.js index 12fcfd8e..3e3d0e5c 100644 --- a/test/api-test.js +++ b/test/api-test.js @@ -419,9 +419,9 @@ describe('RippleAPI', function() { const hash = '0F7ED9F40742D8A513AE86029462B7A6768325583DF8EE21B7EC663019DD6A04'; return this.api.getTransaction(hash).then(() => { - assert(false, 'Should throw ApiError'); + assert(false, 'Should throw UnexpectedError'); }).catch(error => { - assert(error instanceof this.api.errors.ApiError); + assert(error instanceof this.api.errors.UnexpectedError); }); }); }); @@ -854,36 +854,6 @@ describe('RippleAPI', function() { }); - describe('common errors', function() { - - it('TransactionError', function() { - // TransactionError is not used anywhere, so just test its creation - assert.throws(function() { - throw new common.errors.TransactionError('fall through'); - }, this.api.errors.TransactionError); - assert.throws(function() { - throw new common.errors.TransactionError('fall through'); - }, /fall through/); - }); - - it('TimeOutError', function() { - // TimeOutError is not used anywhere, so just test its creation - assert.throws(function() { - throw new common.errors.TimeOutError('fall through'); - }, this.api.errors.TimeOutError); - assert.throws(function() { - throw new common.errors.TimeOutError('fall through'); - }, /fall through/); - }); - - it('RippledNetworkError', function() { - assert.throws(function() { - throw new common.errors.RippledNetworkError(); - }, /Cannot connect to rippled/); - }); - - }); - it('ledgerClosed', function(done) { this.api.on('ledgerClosed', message => { checkResult(responses.ledgerClosed, 'ledgerClosed', message);