fix(server-runtime): ignore duplicate websocket listener (#1829)
This commit is contained in:
@@ -90,6 +90,19 @@ describe('createServer', async () => {
|
||||
await retryStart
|
||||
})
|
||||
|
||||
it('treats EADDRINUSE as an existing listener instead of failing startup', async () => {
|
||||
const server = createServer({ hostname: '127.0.0.1', port: 6121 })
|
||||
|
||||
const startTask = server.start()
|
||||
const error = new Error('listen EADDRINUSE: address already in use 127.0.0.1:6121') as NodeJS.ErrnoException
|
||||
error.code = 'EADDRINUSE'
|
||||
serveMocks.rejectServe(error)
|
||||
|
||||
await expect(startTask).resolves.toBeUndefined()
|
||||
expect(serveMocks.disposeCall).toHaveBeenCalledTimes(1)
|
||||
expect(serveMocks.closeCall).toHaveBeenCalledWith(true)
|
||||
})
|
||||
|
||||
it('merges nested config updates instead of replacing sibling logger settings', async () => {
|
||||
const server = createServer({
|
||||
hostname: '127.0.0.1',
|
||||
|
||||
@@ -32,6 +32,13 @@ export interface Server {
|
||||
updateConfig: (newOptions: ServerOptions) => void
|
||||
}
|
||||
|
||||
function isAddressInUseError(error: unknown) {
|
||||
return typeof error === 'object'
|
||||
&& error !== null
|
||||
&& 'code' in error
|
||||
&& (error as NodeJS.ErrnoException).code === 'EADDRINUSE'
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects local IP addresses that can be used to reach the server from the LAN.
|
||||
*
|
||||
@@ -189,6 +196,10 @@ export function createServer(opts?: ServerOptions): Server {
|
||||
serverInstance = null
|
||||
h3App.dispose()
|
||||
await instance.close(true).catch(() => {})
|
||||
if (isAddressInUseError(error)) {
|
||||
log.withError(error).warn('WebSocket server port already in use, assuming an existing listener is available')
|
||||
return
|
||||
}
|
||||
log.withError(error).error('failed to start WebSocket server')
|
||||
throw error
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user