Skip to content

Commit 24eabed

Browse files
committed
🥅 improve error handling for decode failures, add tests
1 parent a39c4c7 commit 24eabed

File tree

6 files changed

+87
-15
lines changed

6 files changed

+87
-15
lines changed

‎index.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,16 @@ module.exports = function (Adapter) {
116116
if (error)
117117
return error.code === 'ENOENT' ? resolve() : reject(error)
118118

119-
record = msgpack.decode(buffer)
119+
if(buffer.length === 0) {
120+
return reject(new Error(`Decode record failed. File is empty: ${filePath}`))
121+
}
122+
else {
123+
try {
124+
record = msgpack.decode(buffer)
125+
} catch (e) {
126+
return reject(new Error(`Decode record failed. File is corrupt: ${filePath}`, { cause: e }))
127+
}
128+
}
120129

121130
if (!(type in self.db)) self.db[type] = {}
122131

‎package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"lint": "eslint index.js",
1212
"postpublish": "npm run tag",
1313
"tag": "git tag `npm v fortune-fs version` && git push origin --tags",
14-
"test": "npm run lint && node test.js"
14+
"test": "npm run lint && node test/test.js"
1515
},
1616
"dependencies": {
1717
"lockfile": "^1.0.4",

‎test/corrupt-file

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
��id�bar

‎test/empty-file

Whitespace-only changes.

‎test/test.js

Lines changed: 74 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,83 @@
11
'use strict'
22

33
var testAdapter = require('fortune/test/adapter')
4-
var fsAdapter = require('./index')
4+
var fsAdapter = require('../index')
55
const fortune = require('fortune')
6-
const assert = require('node:assert/strict')
6+
const fs = require('node:fs')
7+
const run = require('tapdance')
78

89
testAdapter(fsAdapter)
910

10-
assert.doesNotThrow(() => {
11-
const concurrentReads = 1
12-
const store = fortune({}, {
13-
adapter: [fsAdapter, { concurrentReads }],
14-
})
15-
assert.equal(store.adapter.options.concurrentReads, concurrentReads)
16-
})
11+
run((assert, comment) => {
12+
comment('concurrentReads validation')
13+
14+
let thrown = false
15+
16+
try {
17+
const concurrentReads = 1
18+
const store = fortune({}, {
19+
adapter: [fsAdapter, { concurrentReads }],
20+
})
21+
assert(store.adapter.options.concurrentReads === concurrentReads, `adapter has expected concurrentReads value --- expected: ${store.adapter.options.concurrentReads} --- actual: ${concurrentReads}`)
22+
} catch (e) {
23+
thrown = true
24+
console.error(e)
25+
}
26+
27+
assert(!thrown, 'concurrentReads 1 is valid')
28+
29+
thrown = false
30+
let expectedError
31+
32+
try {
33+
fortune({}, {
34+
adapter: [fsAdapter, { concurrentReads: 0 }],
35+
})
36+
} catch (e) {
37+
thrown = true
38+
expectedError = e.message === 'concurrentReads must be > 0'
39+
if(!expectedError) {
40+
// only log the error if it was something we did not expect
41+
console.error(e)
42+
}
43+
}
44+
45+
assert(thrown, 'concurrentReads 0 is not valid')
46+
assert(expectedError, 'got expected error for concurrentReads 0')
47+
});
48+
49+
(async () => {
50+
51+
run(async (assert, comment) => {
52+
comment('msgpack decode validation')
53+
54+
const store = fortune(
55+
{ foo: { bar: Boolean } },
56+
{ adapter: [fsAdapter] })
57+
58+
fs.mkdirSync('db/foo', { recursive: true })
59+
fs.copyFileSync('test/empty-file', 'db/foo/1')
60+
fs.copyFileSync('test/valid-file', 'db/foo/3')
61+
fs.copyFileSync('test/corrupt-file', 'db/foo/6')
62+
63+
try {
64+
await store.find('foo', [1])
65+
} catch (error) {
66+
// empty
67+
assert(error.message.includes('Decode record failed. File is empty'), `empty error message is present: ${error.message}`)
68+
69+
}
70+
71+
try {
72+
await store.find('foo', [6])
73+
} catch (error) {
74+
// corrupt
75+
assert(error.message.includes('Decode record failed. File is corrupt'), `corrupt error message is present ${error.message}`)
76+
}
77+
78+
const result = await store.find('foo', [3])
79+
assert(result.payload.records.length === 1, 'valid record is found')
1780

18-
assert.throws(() => {
19-
fortune({}, {
20-
adapter: [fsAdapter, { concurrentReads: 0 }],
2181
})
22-
})
82+
83+
})()

‎test/valid-file

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
��id�bar�

0 commit comments

Comments
 (0)