blockstore: close file if write or read throws

This commit is contained in:
Braydon Fuller 2019-04-03 17:34:35 -07:00
parent 3457ccc91b
commit 50fe51ca32
No known key found for this signature in database
GPG Key ID: F24F232D108B3AD4
2 changed files with 76 additions and 5 deletions

View File

@ -383,10 +383,15 @@ class FileBlockStore extends AbstractBlockStore {
const fd = await fs.open(filepath, 'r+');
const mwritten = await fs.write(fd, magic, 0, mlength, mposition);
const bwritten = await fs.write(fd, data, 0, blength, bposition);
let mwritten = 0;
let bwritten = 0;
await fs.close(fd);
try {
mwritten = await fs.write(fd, magic, 0, mlength, mposition);
bwritten = await fs.write(fd, data, 0, blength, bposition);
} finally {
await fs.close(fd);
}
if (mwritten !== mlength) {
this.writing = false;
@ -480,8 +485,13 @@ class FileBlockStore extends AbstractBlockStore {
const data = Buffer.alloc(length);
const fd = await fs.open(filepath, 'r');
const bytes = await fs.read(fd, data, 0, length, position);
await fs.close(fd);
let bytes = 0;
try {
bytes = await fs.read(fd, data, 0, length, position);
} finally {
await fs.close(fd);
}
if (bytes !== length)
throw new Error('Wrong number of bytes read.');

View File

@ -504,6 +504,41 @@ describe('BlockStore', function() {
assert(err, 'Expected error.');
assert.equal(err.message, 'Could not write block.');
});
it('will close file if write throws', async () => {
let err = null;
let closed = null;
store.allocate = () => {
return {
fileno: 20,
filerecord: {
used: 0
},
filepath: '/tmp/.bcoin/blocks/blk00020.dat'
};
};
store.db.has = () => false;
fs.open = () => 7;
fs.close = (fd) => {
closed = fd;
};
fs.write = () => {
throw new Error('Test.');
};
try {
const hash = random.randomBytes(128);
const block = random.randomBytes(32);
await store.write(hash, block);
} catch (e) {
err = e;
}
assert(err, 'Expected error.');
assert.equal(err.message, 'Test.');
assert.equal(closed, 7);
});
});
describe('read', function() {
@ -553,6 +588,32 @@ describe('BlockStore', function() {
assert(err, 'Expected error.');
assert.equal(err.message, 'Wrong number of bytes read.');
});
it('will close file if read throws', async () => {
let err = null;
let closed = null;
store.db.get = () => raw;
fs.open = () => 7;
fs.close = (fd) => {
closed = fd;
};
fs.read = () => {
throw new Error('Test.');
};
try {
const hash = random.randomBytes(128);
const block = random.randomBytes(32);
await store.read(hash, block);
} catch (e) {
err = e;
}
assert(err, 'Expected error.');
assert.equal(err.message, 'Test.');
assert.equal(closed, 7);
});
});
});