Cleanup error classes

This commit is contained in:
Chris Clark
2015-10-27 17:14:23 -07:00
parent 37178eeb0b
commit 87dac75919
5 changed files with 53 additions and 175 deletions

View File

@@ -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));
}
});

View File

@@ -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) {
class RippleError extends Error {
constructor(message) {
super(message);
this.name = this.constructor.name;
this.message = message;
Error.captureStackTrace(this, this.constructor.name);
}
RippleError.prototype = Object.create(Error.prototype);
RippleError.prototype.name = 'RippleError';
RippleError.prototype.toString = function() {
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
to cutomize it output:
https://nodejs.org/api/util.html#util_custom_inspect_function_on_objects
*/
RippleError.prototype.inspect = function(depth) {
utils.unused(depth);
/* 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 RippledError extends RippleError {
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);
this.name = this.constructor.name;
this.message = message;
Error.captureStackTrace(this, this.constructor.name);
super(message || 'Not found');
}
}
class ConnectionError extends RippleError {
class MissingLedgerHistoryError extends RippleError {
constructor(message) {
super(message);
this.name = this.constructor.name;
this.message = message;
Error.captureStackTrace(this, this.constructor.name);
super(message || 'Server is missing ledger history in the specified range');
}
}
class NotConnectedError extends ConnectionError {
class PendingLedgerVersionError extends RippleError {
constructor(message) {
super(message);
super(message || 'maxLedgerVersion is greater than server\'s'
+ 'most recent validated ledger');
}
}
class DisconnectedError extends ConnectionError {
constructor(message) {
super(message);
}
}
class TimeoutError extends ConnectionError {
constructor(message) {
super(message);
}
}
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
};

View File

@@ -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);
}
}

View File

@@ -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');

View File

@@ -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);