From 32109c5de51210bab32c9bcf28ea09d8f2d9b793 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Thu, 21 Jan 2016 14:26:13 -0800 Subject: [PATCH] chaindb: error handling. --- lib/bcoin/chain.js | 68 ++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/lib/bcoin/chain.js b/lib/bcoin/chain.js index 5a229326..442e751e 100644 --- a/lib/bcoin/chain.js +++ b/lib/bcoin/chain.js @@ -834,7 +834,7 @@ ChainDB.prototype.getSync = function getSync(height) { if ((height + 1) * BLOCK_SIZE > this.size) return; - data = this._read(BLOCK_SIZE, height * BLOCK_SIZE); + data = this._readSync(BLOCK_SIZE, height * BLOCK_SIZE); if (!data) return; @@ -872,8 +872,11 @@ ChainDB.prototype.getAsync = function getAsync(height, callback) { this._readAsync(BLOCK_SIZE, height * BLOCK_SIZE, function(err, data) { var entry; + // We can't ensure the integrity of + // the chain if we get an error. + // Just throw. if (err) - return callback(err); + throw err; if (!data) return callback(); @@ -893,7 +896,7 @@ ChainDB.prototype.getAsync = function getAsync(height, callback) { }; ChainDB.prototype.save = function save(entry) { - return this.saveAsync(entry); + return this.saveSync(entry); }; ChainDB.prototype.saveSync = function saveSync(entry) { @@ -907,7 +910,7 @@ ChainDB.prototype.saveSync = function saveSync(entry) { raw = entry.toRaw(); offset = entry.height * BLOCK_SIZE; - return this._write(raw, offset); + return this._writeSync(raw, offset); }; ChainDB.prototype.saveAsync = function saveAsync(entry, callback) { @@ -935,26 +938,25 @@ ChainDB.prototype.saveAsync = function saveAsync(entry, callback) { offset = entry.height * BLOCK_SIZE; return this._writeAsync(raw, offset, function(err, success) { + // We can't ensure the integrity of + // the chain if we get an error. + // Just throw. + if (err) + throw err; + var item = self._queue[entry.height]; // Something tried to write here but couldn't. // Synchronously write it and get it over with. try { if (item && item !== entry) - success = self._write(item.toRaw(), offset); + success = self._writeSync(item.toRaw(), offset); } catch (e) { err = e; } delete self._queue[entry.height]; - if (err) { - if (callback) - return callback(err); - else - throw err; - } - if (callback) return callback(null, success); }); @@ -968,7 +970,7 @@ ChainDB.prototype.remove = function remove(height) { delete this._queue[height]; } - this._write(this._nullBlock, height * BLOCK_SIZE); + this._writeSync(this._nullBlock, height * BLOCK_SIZE); delete this._cache[height]; // If we deleted several blocks at the end, go back @@ -991,13 +993,13 @@ ChainDB.prototype.remove = function remove(height) { }; ChainDB.prototype.isNull = function isNull(height) { - var data = this._read(4, height * BLOCK_SIZE); + var data = this._readSync(4, height * BLOCK_SIZE); if (!data) return false; return utils.read32(data, 0) === 0; }; -ChainDB.prototype._read = function _read(size, offset) { +ChainDB.prototype._readSync = function _readSync(size, offset) { var index = 0; var data, bytes; @@ -1017,13 +1019,15 @@ ChainDB.prototype._read = function _read(size, offset) { } } } catch (e) { - ; + throw e; } this._free(data); + + throw new Error('_readSync() failed.'); }; -ChainDB.prototype._readAsync = function _read(size, offset, callback) { +ChainDB.prototype._readAsync = function _readSync(size, offset, callback) { var self = this; var index = 0; var data, bytes; @@ -1033,7 +1037,7 @@ ChainDB.prototype._readAsync = function _read(size, offset, callback) { data = this._malloc(size); - (function callee() { + (function next() { fs.read(self.fd, data, index, size, offset, function(err, bytes) { if (err) { self._free(data); @@ -1049,7 +1053,7 @@ ChainDB.prototype._readAsync = function _read(size, offset, callback) { return callback(null, data); } - callee(); + next(); }); })(); }; @@ -1065,7 +1069,7 @@ ChainDB.prototype._writeAsync = function _writeAsync(data, offset, callback) { self.size += added; - (function callee() { + (function next() { fs.write(self.fd, data, index, size, offset, function(err, bytes) { if (err) return callback(err); @@ -1077,12 +1081,12 @@ ChainDB.prototype._writeAsync = function _writeAsync(data, offset, callback) { if (index === data.length) return callback(null, true); - callee(); + next(); }); })(); }; -ChainDB.prototype._write = function _write(data, offset) { +ChainDB.prototype._writeSync = function _writeSync(data, offset) { var size = data.length; var added = Math.max(0, (offset + data.length) - this.size); var index = 0; @@ -1091,17 +1095,21 @@ ChainDB.prototype._write = function _write(data, offset) { if (offset < 0 || offset == null) return false; - while (bytes = fs.writeSync(this.fd, data, index, size, offset)) { - index += bytes; - size -= bytes; - offset += bytes; - if (index === data.length) { - this.size += added; - return true; + try { + while (bytes = fs.writeSync(this.fd, data, index, size, offset)) { + index += bytes; + size -= bytes; + offset += bytes; + if (index === data.length) { + this.size += added; + return true; + } } + } catch (e) { + throw e; } - return false; + throw new Error('_writeSync() failed.'); }; /**