Skip to content

Commit dacd6ce

Browse files
authored
feat!: use .name property for errors instead of .code (#315)
Refactors thrown errors to have a `.name` property that describes the type of error, e.g. `NotFoundError` instead of a `.code` property like `ERR_NOT_FOUND`. This is more ideomatic JavaScript as `.code` is largely inherited from errors thrown by Node.js's fs module whereas `.name` reflects the [function (e.g. constructor) name](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name) of the error. Also removes the `err-code` dependency which is another CJS dep down. BREAKING CHANGE: To detect the type of error thrown, use `.name` instead of `.code`
1 parent 7877a67 commit dacd6ce

File tree

37 files changed

+188
-206
lines changed

37 files changed

+188
-206
lines changed

packages/blockstore-core/package.json

-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@
9898
},
9999
"dependencies": {
100100
"@libp2p/logger": "^4.0.6",
101-
"err-code": "^3.0.1",
102101
"interface-blockstore": "^5.0.0",
103102
"interface-store": "^5.0.0",
104103
"it-drain": "^3.0.5",

packages/blockstore-core/src/black-hole.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { NotFoundError } from 'interface-store'
12
import { BaseBlockstore } from './base.js'
2-
import * as Errors from './errors.js'
33
import type { Pair } from 'interface-blockstore'
44
import type { Await, AwaitIterable } from 'interface-store'
55
import type { CID } from 'multiformats/cid'
@@ -10,7 +10,7 @@ export class BlackHoleBlockstore extends BaseBlockstore {
1010
}
1111

1212
get (): Await<Uint8Array> {
13-
throw Errors.notFoundError()
13+
throw new NotFoundError()
1414
}
1515

1616
has (): Await<boolean> {

packages/blockstore-core/src/errors.ts

-41
This file was deleted.

packages/blockstore-core/src/identity.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { NotFoundError } from 'interface-store'
12
import { BaseBlockstore } from './base.js'
2-
import { Errors } from './index.js'
33
import type { Blockstore, Pair } from 'interface-blockstore'
44
import type { AbortOptions, Await, AwaitIterable } from 'interface-store'
55
import type { CID } from 'multiformats/cid'
@@ -34,7 +34,7 @@ export class IdentityBlockstore extends BaseBlockstore {
3434
}
3535

3636
if (this.child == null) {
37-
throw Errors.notFoundError()
37+
throw new NotFoundError()
3838
}
3939

4040
return this.child.get(key)

packages/blockstore-core/src/index.ts

-6
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,7 @@
8282
* ```
8383
*/
8484

85-
import * as ErrorsImport from './errors.js'
86-
8785
export { BaseBlockstore } from './base.js'
8886
export { MemoryBlockstore } from './memory.js'
8987
export { BlackHoleBlockstore } from './black-hole.js'
9088
export { TieredBlockstore } from './tiered.js'
91-
92-
export const Errors = {
93-
...ErrorsImport
94-
}

packages/blockstore-core/src/memory.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
import { NotFoundError } from 'interface-store'
12
import { base32 } from 'multiformats/bases/base32'
23
import { CID } from 'multiformats/cid'
34
import * as raw from 'multiformats/codecs/raw'
45
import * as Digest from 'multiformats/hashes/digest'
56
import { BaseBlockstore } from './base.js'
6-
import * as Errors from './errors.js'
77
import type { Pair } from 'interface-blockstore'
88
import type { Await, AwaitIterable } from 'interface-store'
99

@@ -26,7 +26,7 @@ export class MemoryBlockstore extends BaseBlockstore {
2626
const buf = this.data.get(base32.encode(key.multihash.bytes))
2727

2828
if (buf == null) {
29-
throw Errors.notFoundError()
29+
throw new NotFoundError()
3030
}
3131

3232
return buf

packages/blockstore-core/src/tiered.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { logger } from '@libp2p/logger'
2+
import { DeleteFailedError, NotFoundError, PutFailedError } from 'interface-store'
23
import drain from 'it-drain'
34
import filter from 'it-filter'
45
import merge from 'it-merge'
56
import { pushable } from 'it-pushable'
67
import { BaseBlockstore } from './base.js'
7-
import * as Errors from './errors.js'
88
import type { Blockstore, Pair } from 'interface-blockstore'
99
import type { AbortOptions, AwaitIterable } from 'interface-store'
1010
import type { CID } from 'multiformats/cid'
@@ -31,7 +31,7 @@ export class TieredBlockstore extends BaseBlockstore {
3131
await Promise.all(this.stores.map(async store => { await store.put(key, value, options) }))
3232
return key
3333
} catch (err: any) {
34-
throw Errors.putFailedError(err)
34+
throw new PutFailedError(String(err))
3535
}
3636
}
3737

@@ -44,7 +44,7 @@ export class TieredBlockstore extends BaseBlockstore {
4444
log.error(err)
4545
}
4646
}
47-
throw Errors.notFoundError()
47+
throw new NotFoundError()
4848
}
4949

5050
async has (key: CID, options?: AbortOptions): Promise<boolean> {
@@ -61,7 +61,7 @@ export class TieredBlockstore extends BaseBlockstore {
6161
try {
6262
await Promise.all(this.stores.map(async store => { await store.delete(key, options) }))
6363
} catch (err: any) {
64-
throw Errors.deleteFailedError(err)
64+
throw new DeleteFailedError(String(err))
6565
}
6666
}
6767

packages/blockstore-fs/package.json

-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@
7676
"dep-check": "aegir dep-check"
7777
},
7878
"dependencies": {
79-
"blockstore-core": "^4.0.0",
8079
"fast-write-atomic": "^0.2.1",
8180
"interface-blockstore": "^5.0.0",
8281
"interface-store": "^5.0.0",

packages/blockstore-fs/src/index.ts

+8-10
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,15 @@
1515
import fs from 'node:fs/promises'
1616
import path from 'node:path'
1717
import { promisify } from 'node:util'
18-
import {
19-
Errors
20-
} from 'blockstore-core'
2118
// @ts-expect-error no types
2219
import fwa from 'fast-write-atomic'
20+
import { OpenFailedError, type AwaitIterable, PutFailedError, NotFoundError, DeleteFailedError } from 'interface-store'
2321
import glob from 'it-glob'
2422
import map from 'it-map'
2523
import parallelBatch from 'it-parallel-batch'
26-
import { NextToLast, type ShardingStrategy } from './sharding.js'
24+
import { NextToLast } from './sharding.js'
25+
import type { ShardingStrategy } from './sharding.js'
2726
import type { Blockstore, Pair } from 'interface-blockstore'
28-
import type { AwaitIterable } from 'interface-store'
2927
import type { CID } from 'multiformats/cid'
3028

3129
const writeAtomic = promisify(fwa)
@@ -122,15 +120,15 @@ export class FsBlockstore implements Blockstore {
122120
await fs.access(this.path, fs.constants.F_OK | fs.constants.W_OK)
123121

124122
if (this.errorIfExists) {
125-
throw Errors.openFailedError(new Error(`Blockstore directory: ${this.path} already exists`))
123+
throw new OpenFailedError(`Blockstore directory: ${this.path} already exists`)
126124
}
127125
} catch (err: any) {
128126
if (err.code === 'ENOENT') {
129127
if (this.createIfMissing) {
130128
await fs.mkdir(this.path, { recursive: true })
131129
return
132130
} else {
133-
throw Errors.openFailedError(new Error(`Blockstore directory: ${this.path} does not exist`))
131+
throw new OpenFailedError(`Blockstore directory: ${this.path} does not exist`)
134132
}
135133
}
136134

@@ -156,7 +154,7 @@ export class FsBlockstore implements Blockstore {
156154

157155
return key
158156
} catch (err: any) {
159-
throw Errors.putFailedError(err)
157+
throw new PutFailedError(String(err))
160158
}
161159
}
162160

@@ -179,7 +177,7 @@ export class FsBlockstore implements Blockstore {
179177
try {
180178
return await fs.readFile(path.join(this.path, dir, file))
181179
} catch (err: any) {
182-
throw Errors.notFoundError(err)
180+
throw new NotFoundError(String(err))
183181
}
184182
}
185183

@@ -207,7 +205,7 @@ export class FsBlockstore implements Blockstore {
207205
return
208206
}
209207

210-
throw Errors.deleteFailedError(err)
208+
throw new DeleteFailedError(String(err))
211209
}
212210
}
213211

packages/blockstore-fs/test/index.spec.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-env mocha */
21
import fs from 'node:fs/promises'
32
import os from 'node:os'
43
import path from 'node:path'
@@ -44,7 +43,7 @@ describe('FsBlockstore', () => {
4443
const dir = path.join(os.tmpdir(), `test-${Math.random()}`)
4544
const store = new FsBlockstore(dir, { createIfMissing: false })
4645
await expect(store.open()).to.eventually.be.rejected
47-
.with.property('code', 'ERR_OPEN_FAILED')
46+
.with.property('name', 'OpenFailedError')
4847
})
4948

5049
it('errorIfExists: true - folder exists', async () => {
@@ -54,7 +53,7 @@ describe('FsBlockstore', () => {
5453
})
5554
const store = new FsBlockstore(dir, { errorIfExists: true })
5655
await expect(store.open()).to.eventually.be.rejected
57-
.with.property('code', 'ERR_OPEN_FAILED')
56+
.with.property('name', 'OpenFailedError')
5857
})
5958
})
6059

@@ -68,7 +67,7 @@ describe('FsBlockstore', () => {
6867
await fs.delete(key)
6968

7069
await expect(fs.get(key)).to.eventually.be.rejected
71-
.with.property('code', 'ERR_NOT_FOUND')
70+
.with.property('name', 'NotFoundError')
7271
})
7372

7473
it('deleting non-existent files', async () => {
@@ -81,7 +80,7 @@ describe('FsBlockstore', () => {
8180
await fs.delete(key)
8281

8382
await expect(fs.get(key)).to.eventually.be.rejected
84-
.with.property('code', 'ERR_NOT_FOUND')
83+
.with.property('name', 'NotFoundError')
8584
})
8685

8786
describe('interface-blockstore (flat directory)', () => {

packages/blockstore-idb/src/index.ts

+10-11
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,14 @@
1212
* ```
1313
*/
1414

15-
import {
16-
BaseBlockstore,
17-
Errors
18-
} from 'blockstore-core'
19-
import { openDB, type IDBPDatabase, deleteDB } from 'idb'
15+
import { BaseBlockstore } from 'blockstore-core'
16+
import { openDB, deleteDB } from 'idb'
17+
import { OpenFailedError, PutFailedError, NotFoundError } from 'interface-store'
2018
import { base32upper } from 'multiformats/bases/base32'
2119
import { CID } from 'multiformats/cid'
2220
import * as raw from 'multiformats/codecs/raw'
2321
import * as Digest from 'multiformats/hashes/digest'
22+
import type { IDBPDatabase } from 'idb'
2423
import type { Pair } from 'interface-blockstore'
2524
import type { AbortOptions, AwaitIterable } from 'interface-store'
2625
import type { MultibaseCodec } from 'multiformats/bases/interface'
@@ -77,7 +76,7 @@ export class IDBBlockstore extends BaseBlockstore {
7776
}
7877
})
7978
} catch (err: any) {
80-
throw Errors.openFailedError(err)
79+
throw new OpenFailedError(String(err))
8180
}
8281
}
8382

@@ -95,7 +94,7 @@ export class IDBBlockstore extends BaseBlockstore {
9594

9695
return key
9796
} catch (err: any) {
98-
throw Errors.putFailedError(err)
97+
throw new PutFailedError(String(err))
9998
}
10099
}
101100

@@ -109,11 +108,11 @@ export class IDBBlockstore extends BaseBlockstore {
109108
try {
110109
val = await this.db.get(this.location, this.#encode(key))
111110
} catch (err: any) {
112-
throw Errors.putFailedError(err)
111+
throw new PutFailedError(String(err))
113112
}
114113

115114
if (val === undefined) {
116-
throw Errors.notFoundError()
115+
throw new NotFoundError()
117116
}
118117

119118
return val
@@ -127,7 +126,7 @@ export class IDBBlockstore extends BaseBlockstore {
127126
try {
128127
await this.db.delete(this.location, this.#encode(key))
129128
} catch (err: any) {
130-
throw Errors.putFailedError(err)
129+
throw new PutFailedError(String(err))
131130
}
132131
}
133132

@@ -139,7 +138,7 @@ export class IDBBlockstore extends BaseBlockstore {
139138
try {
140139
return Boolean(await this.db.getKey(this.location, this.#encode(key)))
141140
} catch (err: any) {
142-
throw Errors.putFailedError(err)
141+
throw new PutFailedError(String(err))
143142
}
144143
}
145144

packages/blockstore-level/src/index.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
* ```
1515
*/
1616

17-
import { BaseBlockstore, Errors } from 'blockstore-core'
17+
import { BaseBlockstore } from 'blockstore-core'
18+
import { DeleteFailedError, GetFailedError, NotFoundError, OpenFailedError, PutFailedError } from 'interface-store'
1819
import { Level } from 'level'
1920
import { base32upper } from 'multiformats/bases/base32'
2021
import { CID } from 'multiformats/cid'
@@ -73,7 +74,7 @@ export class LevelBlockstore extends BaseBlockstore {
7374
try {
7475
await this.db.open(this.opts)
7576
} catch (err: any) {
76-
throw Errors.openFailedError(err)
77+
throw new OpenFailedError(String(err))
7778
}
7879
}
7980

@@ -83,7 +84,7 @@ export class LevelBlockstore extends BaseBlockstore {
8384

8485
return key
8586
} catch (err: any) {
86-
throw Errors.putFailedError(err)
87+
throw new PutFailedError(String(err))
8788
}
8889
}
8990

@@ -93,10 +94,10 @@ export class LevelBlockstore extends BaseBlockstore {
9394
data = await this.db.get(this.#encode(key))
9495
} catch (err: any) {
9596
if (err.notFound != null) {
96-
throw Errors.notFoundError(err)
97+
throw new NotFoundError(String(err))
9798
}
9899

99-
throw Errors.getFailedError(err)
100+
throw new GetFailedError(String(err))
100101
}
101102
return data
102103
}
@@ -118,7 +119,7 @@ export class LevelBlockstore extends BaseBlockstore {
118119
try {
119120
await this.db.del(this.#encode(key))
120121
} catch (err: any) {
121-
throw Errors.deleteFailedError(err)
122+
throw new DeleteFailedError(String(err))
122123
}
123124
}
124125

0 commit comments

Comments
 (0)