import WebSocket from 'isomorphic-ws' import {format} from 'node:util' import {normalizeError, normalizeProtocolError} from '#common/errors' import {preauthHandler} from './handler-preauth' import {realmHandler} from './handler-realm' import {attachSocket, detachSocket} from './state' /** when the socket connects, we drive our protocol through handlers */ export async function socketHandler(ws: WebSocket) { try { const auth = await preauthHandler(ws) try { await attachSocket(auth.realm, auth.identid, ws) await realmHandler(ws, auth) } finally { await detachSocket(auth.realm, auth.identid, ws) } } catch (exc) { const error = normalizeError(exc) const failure = normalizeProtocolError(error) if (failure.status >= 500) { console.error('fatal:', error) if (error.cause) console.error('cause:', error.cause) } const message = format('Error: %s', failure.message) if (ws.readyState === ws.OPEN) ws.send(message) } finally { if (ws.readyState !== ws.CLOSED) { ws.send(`kthxbye\n`) ws.close() } } }