bitcoind: wrap rpc errors as instances of error
This commit is contained in:
parent
3ead5928a7
commit
82232c0f55
@ -183,24 +183,30 @@ Bitcoin.prototype._resetCaches = function() {
|
||||
this.summaryCache.reset();
|
||||
};
|
||||
|
||||
Bitcoin.prototype._wrapRPCError = function(errObj) {
|
||||
var err = new Error(errObj.message);
|
||||
err.code = errObj.code;
|
||||
return err;
|
||||
};
|
||||
|
||||
Bitcoin.prototype._initChain = function(callback) {
|
||||
var self = this;
|
||||
|
||||
self.client.getBestBlockHash(function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
|
||||
self.client.getBlock(response.result, function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
|
||||
self.height = response.result.height;
|
||||
|
||||
self.client.getBlockHash(0, function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
var blockhash = response.result;
|
||||
self.getBlock(blockhash, function(err, block) {
|
||||
@ -239,7 +245,7 @@ Bitcoin.prototype._zmqBlockHandler = function(node, message) {
|
||||
self.tiphash = message.toString('hex');
|
||||
node.client.getBlock(self.tiphash, function(err, response) {
|
||||
if (err) {
|
||||
return log.error(err);
|
||||
return log.error(self._wrapRPCError(err));
|
||||
}
|
||||
self.height = response.result.height;
|
||||
$.checkState(self.height >= 0);
|
||||
@ -318,7 +324,7 @@ Bitcoin.prototype._checkReindex = function(node, callback) {
|
||||
var interval = setInterval(function() {
|
||||
node.client.syncPercentage(function(err, percentSynced) {
|
||||
if (err) {
|
||||
return log.error(err);
|
||||
return log.error(self._wrapRPCError(err));
|
||||
}
|
||||
log.info('Bitcoin Core Daemon Reindex Percentage: ' + percentSynced.toFixed(2));
|
||||
if (Math.round(percentSynced) >= 100) {
|
||||
@ -339,15 +345,15 @@ Bitcoin.prototype._checkReindex = function(node, callback) {
|
||||
Bitcoin.prototype._loadTipFromNode = function(node, callback) {
|
||||
var self = this;
|
||||
node.client.getBestBlockHash(function(err, response) {
|
||||
if (err) {
|
||||
if (!(err instanceof Error)) {
|
||||
log.warn(err.message);
|
||||
}
|
||||
return callback(new Error('Could not connect to bitcoind RPC'));
|
||||
if (err && err.code === -28) {
|
||||
log.warn(err.message);
|
||||
return callback(self._wrapRPCError(err));
|
||||
} else if (err) {
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
node.client.getBlock(response.result, function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
self.height = response.result.height;
|
||||
$.checkState(self.height >= 0);
|
||||
@ -518,9 +524,10 @@ Bitcoin.prototype.isSynced = function(callback) {
|
||||
* @returns {Number} An estimated percentage of the syncronization status
|
||||
*/
|
||||
Bitcoin.prototype.syncPercentage = function(callback) {
|
||||
var self = this;
|
||||
this.client.getBlockchainInfo(function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
var percentSynced = response.result.verificationprogress * 100;
|
||||
callback(null, percentSynced);
|
||||
@ -542,7 +549,7 @@ Bitcoin.prototype.getAddressBalance = function(addressArg, options, callback) {
|
||||
} else {
|
||||
this.client.getAddressBalance({addresses: addresses}, function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
self.balanceCache.set(cacheKey, response.result);
|
||||
callback(null, response.result);
|
||||
@ -565,7 +572,7 @@ Bitcoin.prototype.getAddressUnspentOutputs = function(addressArg, options, callb
|
||||
} else {
|
||||
self.client.getAddressUtxos({addresses: addresses}, function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
self.utxosCache.set(cacheKey, response.result);
|
||||
callback(null, response.result);
|
||||
@ -614,7 +621,7 @@ Bitcoin.prototype.getAddressTxids = function(addressArg, options, callback) {
|
||||
} else {
|
||||
self.client.getAddressTxids({addresses: addresses}, function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
response.result.reverse();
|
||||
self.txidsCache.set(cacheKey, response.result);
|
||||
@ -627,7 +634,7 @@ Bitcoin.prototype.getAddressTxids = function(addressArg, options, callback) {
|
||||
if (queryMempool) {
|
||||
self.client.getAddressMempool({addresses: addresses}, function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
mempoolTxids = self._getTxidsFromMempool(response.result);
|
||||
finish();
|
||||
@ -850,7 +857,7 @@ Bitcoin.prototype.getAddressSummary = function(addressArg, options, callback) {
|
||||
}
|
||||
self.client.getAddressMempool({'addresses': [addressArg]}, function(err, response) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
return done(self._wrapRPCError(err));
|
||||
}
|
||||
mempoolTxids = self._getTxidsFromMempool(response.result);
|
||||
summary.unconfirmedAppearances = mempoolTxids.length;
|
||||
@ -895,7 +902,7 @@ Bitcoin.prototype.getBlock = function(blockArg, callback) {
|
||||
function queryBlock(blockhash) {
|
||||
self.client.getBlock(blockhash, false, function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
var blockObj = bitcore.Block.fromString(response.result);
|
||||
self.blockCache.set(blockArg, blockObj);
|
||||
@ -912,7 +919,7 @@ Bitcoin.prototype.getBlock = function(blockArg, callback) {
|
||||
if (_.isNumber(blockArg)) {
|
||||
self.client.getBlockHash(blockArg, function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
var blockhash = response.result;
|
||||
queryBlock(blockhash);
|
||||
@ -928,7 +935,7 @@ Bitcoin.prototype.getBlockHashesByTimestamp = function(high, low, callback) {
|
||||
var self = this;
|
||||
self.client.getBlockHashes(high, low, function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
callback(null, response.result);
|
||||
});
|
||||
@ -954,7 +961,7 @@ Bitcoin.prototype.getBlockHeader = function(block, callback) {
|
||||
if (err && response.error.code === -5) {
|
||||
return callback(null, null);
|
||||
} else if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
// TODO format response prevHash instead of previousblockhash, etc.
|
||||
callback(null, response.result);
|
||||
@ -966,7 +973,7 @@ Bitcoin.prototype.getBlockHeader = function(block, callback) {
|
||||
if (err && response.error.code === -8) {
|
||||
return callback(null, null);
|
||||
} else if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
var blockhash = response.result;
|
||||
queryHeader(blockhash);
|
||||
@ -982,9 +989,10 @@ Bitcoin.prototype.getBlockHeader = function(block, callback) {
|
||||
* @returns {Number}
|
||||
*/
|
||||
Bitcoin.prototype.estimateFee = function(blocks, callback) {
|
||||
var self = this;
|
||||
this.client.estimateFee(blocks, function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
callback(null, response.result);
|
||||
});
|
||||
@ -997,6 +1005,7 @@ Bitcoin.prototype.estimateFee = function(blocks, callback) {
|
||||
* @param {Boolean} allowAbsurdFees - Enable large fees
|
||||
*/
|
||||
Bitcoin.prototype.sendTransaction = function(tx, allowAbsurdFees, callback) {
|
||||
var self = this;
|
||||
var txString;
|
||||
if (tx instanceof Transaction) {
|
||||
txString = tx.serialize();
|
||||
@ -1010,7 +1019,7 @@ Bitcoin.prototype.sendTransaction = function(tx, allowAbsurdFees, callback) {
|
||||
|
||||
this.client.sendRawTransaction(txString, allowAbsurdFees, function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
callback(null, response.result);
|
||||
});
|
||||
@ -1035,7 +1044,7 @@ Bitcoin.prototype.getTransaction = function(txid, queryMempool, callback) {
|
||||
if (err && response.error.code === -5) {
|
||||
return callback(null, null);
|
||||
} else if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
var tx = Transaction();
|
||||
tx.fromString(response.result);
|
||||
@ -1066,11 +1075,10 @@ Bitcoin.prototype.getTransactionWithBlockInfo = function(txid, queryMempool, cal
|
||||
});
|
||||
} else {
|
||||
self.client.getRawTransaction(txid, 1, function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
if (!response.result) {
|
||||
return callback(new errors.Transaction.NotFound());
|
||||
if (err && response.error.code === -5) {
|
||||
return callback(null, null);
|
||||
} else if (err) {
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
var tx = Transaction();
|
||||
tx.fromString(response.result.hex);
|
||||
@ -1091,9 +1099,10 @@ Bitcoin.prototype.getTransactionWithBlockInfo = function(txid, queryMempool, cal
|
||||
* @returns {String}
|
||||
*/
|
||||
Bitcoin.prototype.getBestBlockHash = function(callback) {
|
||||
var self = this;
|
||||
this.client.getBestBlockHash(function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
callback(null, response.result);
|
||||
});
|
||||
@ -1122,7 +1131,7 @@ Bitcoin.prototype.getInfo = function(callback) {
|
||||
var self = this;
|
||||
this.client.getInfo(function(err, response) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
var result = response.result;
|
||||
result.network = self.node.network.name;
|
||||
|
||||
@ -32,7 +32,7 @@ Transaction.prototype._populateInput = function(db, input, poolTransactions, cal
|
||||
}
|
||||
var txid = input.prevTxId.toString('hex');
|
||||
db.getTransaction(txid, true, function(err, prevTx) {
|
||||
if(err instanceof errors.Transaction.NotFoundError) {
|
||||
if(!prevTx) {
|
||||
// Check the pool for transaction
|
||||
for(var i = 0; i < poolTransactions.length; i++) {
|
||||
if(txid === poolTransactions[i].hash) {
|
||||
|
||||
@ -149,6 +149,19 @@ describe('Bitcoind Functionality', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('get errors as error instances', function() {
|
||||
it('will wrap an rpc into a javascript error', function(done) {
|
||||
bitcoind.client.getBlock(1000000000, function(err, response) {
|
||||
var error = bitcoind._wrapRPCError(err);
|
||||
(error instanceof Error).should.equal(true);
|
||||
error.message.should.equal(err.message);
|
||||
error.code.should.equal(err.code);
|
||||
should.exist(error.stack);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('get blocks by height', function() {
|
||||
|
||||
[0,1,2,3,4,5,6,7,8,9].forEach(function(i) {
|
||||
@ -303,6 +316,7 @@ describe('Bitcoind Functionality', function() {
|
||||
tx.to(destKey.toAddress(), utxos[1].amount * 1e8 - 1000);
|
||||
bitcoind.sendTransaction(tx.uncheckedSerialize(), function(err, hash) {
|
||||
should.exist(err);
|
||||
(err instanceof Error).should.equal(true);
|
||||
should.not.exist(hash);
|
||||
done();
|
||||
});
|
||||
@ -316,6 +330,7 @@ describe('Bitcoind Functionality', function() {
|
||||
var num = 23;
|
||||
bitcoind.sendTransaction(num, function(err, hash) {
|
||||
should.exist(err);
|
||||
(err instanceof Error).should.equal(true);
|
||||
should.not.exist(hash);
|
||||
done();
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user