Skip to content

Commit 3b683e7

Browse files
Robert KielRobert Kielachingbrain
authored
fix: fix uncaught promise rejection when finding peers (#1044)
Do not abort all attempts to find peers when `findPeers` on one router throws synchronously Co-authored-by: Robert Kiel <robert.kiel@hoprnet.io> Co-authored-by: achingbrain <alex@achingbrain.net>
1 parent b25e0fe commit 3b683e7

File tree

2 files changed

+96
-2
lines changed

2 files changed

+96
-2
lines changed

src/peer-routing.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,15 @@ class PeerRouting {
114114

115115
const output = await pipe(
116116
merge(
117-
...this._routers.map(router => [router.findPeer(id, options)])
117+
...this._routers.map(router => (async function * () {
118+
try {
119+
yield await router.findPeer(id, options)
120+
} catch (err) {
121+
log.error(err)
122+
}
123+
})())
118124
),
119125
(source) => filter(source, Boolean),
120-
// @ts-ignore findPeer resolves a Promise
121126
(source) => storeAddresses(source, this._peerStore),
122127
(source) => first(source)
123128
)

test/peer-routing/peer-routing.node.js

+89
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,95 @@ describe('peer-routing', () => {
106106
.to.eventually.be.rejected()
107107
.and.to.have.property('code', 'ERR_FIND_SELF')
108108
})
109+
110+
it('should handle error thrown synchronously during find peer', async () => {
111+
const unknownPeers = await peerUtils.createPeerId({ number: 1, fixture: false })
112+
113+
nodes[0].peerRouting._routers = [{
114+
findPeer () {
115+
throw new Error('Thrown sync')
116+
}
117+
}]
118+
119+
await expect(nodes[0].peerRouting.findPeer(unknownPeers[0]))
120+
.to.eventually.be.rejected()
121+
.and.to.have.property('code', 'ERR_NOT_FOUND')
122+
})
123+
124+
it('should handle error thrown asynchronously during find peer', async () => {
125+
const unknownPeers = await peerUtils.createPeerId({ number: 1, fixture: false })
126+
127+
nodes[0].peerRouting._routers = [{
128+
async findPeer () {
129+
throw new Error('Thrown async')
130+
}
131+
}]
132+
133+
await expect(nodes[0].peerRouting.findPeer(unknownPeers[0]))
134+
.to.eventually.be.rejected()
135+
.and.to.have.property('code', 'ERR_NOT_FOUND')
136+
})
137+
138+
it('should handle error thrown asynchronously after delay during find peer', async () => {
139+
const unknownPeers = await peerUtils.createPeerId({ number: 1, fixture: false })
140+
141+
nodes[0].peerRouting._routers = [{
142+
async findPeer () {
143+
await delay(100)
144+
throw new Error('Thrown async after delay')
145+
}
146+
}]
147+
148+
await expect(nodes[0].peerRouting.findPeer(unknownPeers[0]))
149+
.to.eventually.be.rejected()
150+
.and.to.have.property('code', 'ERR_NOT_FOUND')
151+
})
152+
153+
it('should return value when one router errors synchronously and another returns a value', async () => {
154+
const [peer] = await peerUtils.createPeerId({ number: 1, fixture: false })
155+
156+
nodes[0].peerRouting._routers = [{
157+
findPeer () {
158+
throw new Error('Thrown sync')
159+
}
160+
}, {
161+
async findPeer () {
162+
return Promise.resolve({
163+
id: peer,
164+
multiaddrs: []
165+
})
166+
}
167+
}]
168+
169+
await expect(nodes[0].peerRouting.findPeer(peer))
170+
.to.eventually.deep.equal({
171+
id: peer,
172+
multiaddrs: []
173+
})
174+
})
175+
176+
it('should return value when one router errors asynchronously and another returns a value', async () => {
177+
const [peer] = await peerUtils.createPeerId({ number: 1, fixture: false })
178+
179+
nodes[0].peerRouting._routers = [{
180+
async findPeer () {
181+
throw new Error('Thrown sync')
182+
}
183+
}, {
184+
async findPeer () {
185+
return Promise.resolve({
186+
id: peer,
187+
multiaddrs: []
188+
})
189+
}
190+
}]
191+
192+
await expect(nodes[0].peerRouting.findPeer(peer))
193+
.to.eventually.deep.equal({
194+
id: peer,
195+
multiaddrs: []
196+
})
197+
})
109198
})
110199

111200
describe('via delegate router', () => {

0 commit comments

Comments
 (0)