Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

Commit 45b80a0

Browse files
authored
fix: emit boot error only once (#1472)
`init` and `start` both emit any error they encounter. `boot` will then receive that error and also emit it! This PR adds an `emitted` property in `boot` to errors that came from `init` or `start` so that later in the code it knows whether to emit it or not! License: MIT Signed-off-by: Alan Shaw <[email protected]>
1 parent 1f63e8c commit 45b80a0

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

src/core/boot.js

+17-4
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,21 @@ module.exports = (self) => {
3030
(repoOpened, cb) => {
3131
// Init with existing initialized, opened, repo
3232
if (repoOpened) {
33-
return self.init({ repo: self._repo }, (err) => cb(err))
33+
return self.init({ repo: self._repo }, (err) => {
34+
if (err) return cb(Object.assign(err, { emitted: true }))
35+
cb()
36+
})
3437
}
3538

3639
if (doInit) {
3740
const initOptions = Object.assign(
3841
{ bits: 2048, pass: self._options.pass },
3942
typeof options.init === 'object' ? options.init : {}
4043
)
41-
return self.init(initOptions, (err) => cb(err))
44+
return self.init(initOptions, (err) => {
45+
if (err) return cb(Object.assign(err, { emitted: true }))
46+
cb()
47+
})
4248
}
4349

4450
cb()
@@ -48,11 +54,18 @@ module.exports = (self) => {
4854
if (!doStart) {
4955
return cb()
5056
}
51-
self.start(cb)
57+
58+
self.start((err) => {
59+
if (err) return cb(Object.assign(err, { emitted: true }))
60+
cb()
61+
})
5262
}
5363
], (err) => {
5464
if (err) {
55-
return self.emit('error', err)
65+
if (!err.emitted) {
66+
self.emit('error', err)
67+
}
68+
return
5669
}
5770
self.log('booted')
5871
self.emit('ready')

test/core/create-node.spec.js

+19-5
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ describe('create node', function () {
123123
})
124124
})
125125

126-
it('init: false errors (start default: true)', function (done) {
126+
it('init: false errors (start default: true) and errors only once', function (done) {
127127
this.timeout(80 * 1000)
128128

129129
const node = new IPFS({
@@ -135,10 +135,24 @@ describe('create node', function () {
135135
}
136136
}
137137
})
138-
node.once('error', (err) => {
139-
expect(err).to.exist()
140-
done()
141-
})
138+
139+
const shouldHappenOnce = () => {
140+
let timeoutId = null
141+
142+
return (err) => {
143+
expect(err).to.exist()
144+
145+
// Bad news, this handler has been executed before
146+
if (timeoutId) {
147+
clearTimeout(timeoutId)
148+
return done(new Error('error handler called multiple times'))
149+
}
150+
151+
timeoutId = setTimeout(done, 100)
152+
}
153+
}
154+
155+
node.on('error', shouldHappenOnce())
142156
})
143157

144158
it('init: false, start: false', function (done) {

0 commit comments

Comments
 (0)