podcast manager
at main 37 lines 1.1 kB view raw
1import WebSocket from 'isomorphic-ws' 2import {format} from 'node:util' 3 4import {normalizeError, normalizeProtocolError} from '#common/errors' 5 6import {preauthHandler} from './handler-preauth' 7import {realmHandler} from './handler-realm' 8import {attachSocket, detachSocket} from './state' 9 10/** when the socket connects, we drive our protocol through handlers */ 11export async function socketHandler(ws: WebSocket) { 12 try { 13 const auth = await preauthHandler(ws) 14 try { 15 await attachSocket(auth.realm, auth.identid, ws) 16 await realmHandler(ws, auth) 17 } finally { 18 await detachSocket(auth.realm, auth.identid, ws) 19 } 20 } catch (exc) { 21 const error = normalizeError(exc) 22 const failure = normalizeProtocolError(error) 23 24 if (failure.status >= 500) { 25 console.error('fatal:', error) 26 if (error.cause) console.error('cause:', error.cause) 27 } 28 29 const message = format('Error: %s', failure.message) 30 if (ws.readyState === ws.OPEN) ws.send(message) 31 } finally { 32 if (ws.readyState !== ws.CLOSED) { 33 ws.send(`kthxbye\n`) 34 ws.close() 35 } 36 } 37}