Skip to content

Commit ab1bb86

Browse files
authored
fix: improve error message when starting server (#3008)
When transports fail to listen, include specific error messages and advice on how to proceed.
1 parent f3d9f56 commit ab1bb86

File tree

4 files changed

+33
-12
lines changed

4 files changed

+33
-12
lines changed

packages/integration-tests/test/listening.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ describe('Listening', () => {
5353
})
5454

5555
await expect(libp2p.start()).to.eventually.be.rejected
56-
.with.property('name', 'NoValidAddressesError')
56+
.with.property('name', 'UnsupportedListenAddressesError')
5757
})
5858

5959
it('does not fail to start if provided listen multiaddr are not compatible to configured transports (when supporting dial only mode)', async () => {

packages/libp2p/src/errors.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,20 @@ export class DialDeniedError extends Error {
5959
}
6060
}
6161

62+
export class UnsupportedListenAddressError extends Error {
63+
constructor (message = 'No transport was configured to listen on this address') {
64+
super(message)
65+
this.name = 'UnsupportedListenAddressError'
66+
}
67+
}
68+
69+
export class UnsupportedListenAddressesError extends Error {
70+
constructor (message = 'Configured listen addresses could not be listened on') {
71+
super(message)
72+
this.name = 'UnsupportedListenAddressesError'
73+
}
74+
}
75+
6276
export class NoValidAddressesError extends Error {
6377
constructor (message = 'No valid addresses') {
6478
super(message)

packages/libp2p/src/transport-manager.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { FaultTolerance, InvalidParametersError, NotStartedError } from '@libp2p
22
import { trackedMap } from '@libp2p/utils/tracked-map'
33
import { IP4, IP6 } from '@multiformats/multiaddr-matcher'
44
import { CustomProgressEvent } from 'progress-events'
5-
import { NoValidAddressesError, TransportUnavailableError } from './errors.js'
5+
import { TransportUnavailableError, UnsupportedListenAddressError, UnsupportedListenAddressesError } from './errors.js'
66
import type { Libp2pEvents, ComponentLogger, Logger, Connection, TypedEventTarget, Metrics, Startable, Listener, Transport, Upgrader } from '@libp2p/interface'
77
import type { AddressManager, TransportManager, TransportManagerDialOptions } from '@libp2p/interface-internal'
88
import type { Multiaddr } from '@multiformats/multiaddr'
@@ -25,7 +25,7 @@ interface IPStats {
2525
}
2626

2727
interface ListenStats {
28-
unsupportedAddresses: Set<string>
28+
errors: Map<string, Error>
2929
ipv4: IPStats
3030
ipv6: IPStats
3131
}
@@ -207,9 +207,7 @@ export class DefaultTransportManager implements TransportManager, Startable {
207207
// track IPv4/IPv6 results - if we succeed on IPv4 but all IPv6 attempts
208208
// fail then we are probably on a network without IPv6 support
209209
const listenStats: ListenStats = {
210-
unsupportedAddresses: new Set(
211-
addrs.map(ma => ma.toString())
212-
),
210+
errors: new Map(),
213211
ipv4: {
214212
success: 0,
215213
attempts: 0
@@ -220,6 +218,10 @@ export class DefaultTransportManager implements TransportManager, Startable {
220218
}
221219
}
222220

221+
addrs.forEach(ma => {
222+
listenStats.errors.set(ma.toString(), new UnsupportedListenAddressError())
223+
})
224+
223225
const tasks: Array<Promise<void>> = []
224226

225227
for (const [key, transport] of this.transports.entries()) {
@@ -269,7 +271,7 @@ export class DefaultTransportManager implements TransportManager, Startable {
269271
tasks.push(
270272
listener.listen(addr)
271273
.then(() => {
272-
listenStats.unsupportedAddresses.delete(addr.toString())
274+
listenStats.errors.delete(addr.toString())
273275

274276
if (IP4.matches(addr)) {
275277
listenStats.ipv4.success++
@@ -280,6 +282,7 @@ export class DefaultTransportManager implements TransportManager, Startable {
280282
}
281283
}, (err) => {
282284
this.log.error('transport %s could not listen on address %a - %e', key, addr, err)
285+
listenStats.errors.set(addr.toString(), err)
283286
throw err
284287
})
285288
)
@@ -308,9 +311,13 @@ export class DefaultTransportManager implements TransportManager, Startable {
308311
}
309312

310313
// if a configured address was not able to be listened on, throw an error
311-
throw new NoValidAddressesError(`No configured transport could listen on these addresses, please remove them from your config: ${[
312-
...listenStats.unsupportedAddresses
313-
].join(', ')}`)
314+
throw new UnsupportedListenAddressesError(`Some configured addresses failed to be listened on, you may need to remove one or more listen addresses from your configuration or set \`transportManager.faultTolerance\` to NO_FATAL:\n${
315+
[...listenStats.errors.entries()].map(([addr, err]) => {
316+
return `
317+
${addr}: ${`${err.stack ?? err}`.split('\n').join('\n ')}
318+
`
319+
}).join('')
320+
}`)
314321
}
315322

316323
private ipv6Unsupported (listenStats: ListenStats): boolean {

packages/libp2p/test/transports/transport-manager.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ describe('Transport Manager', () => {
123123

124124
await expect(start(tm))
125125
.to.eventually.be.rejected()
126-
.and.to.have.property('name', 'NoValidAddressesError')
126+
.and.to.have.property('name', 'UnsupportedListenAddressesError')
127127

128128
await stop(tm)
129129
})
@@ -167,7 +167,7 @@ describe('Transport Manager', () => {
167167
transportManager.add(transport)
168168

169169
await expect(start(transportManager)).to.eventually.be.rejected
170-
.with.property('name', 'NoValidAddressesError')
170+
.with.property('name', 'UnsupportedListenAddressesError')
171171
})
172172

173173
it('should detect lack of IPv6 support', async () => {

0 commit comments

Comments
 (0)