Skip to content

Commit bdd29a9

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

File tree

6 files changed

+85
-11
lines changed

6 files changed

+85
-11
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: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,85 @@
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+
run((assert, comment) => {
12+
comment('concurrentReads validation')
13+
1114
const concurrentReads = 1
15+
1216
const store = fortune({}, {
1317
adapter: [fsAdapter, { concurrentReads }],
1418
})
15-
assert.equal(store.adapter.options.concurrentReads, concurrentReads)
16-
})
1719

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

‎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)