(raw: Buffer)
| 163 | } |
| 164 | |
| 165 | private async onClientMessage(raw: Buffer) { |
| 166 | this.alive = true |
| 167 | let abortable = false |
| 168 | let messageHandler: (IMessageHandler & IAbortable) | undefined = undefined |
| 169 | try { |
| 170 | if (await this.isRateLimited(this.clientAddress.address)) { |
| 171 | this.sendMessage(createNoticeMessage('rate limited')) |
| 172 | return |
| 173 | } |
| 174 | |
| 175 | const message = attemptValidation(messageSchema)(JSON.parse(raw.toString('utf8'))) |
| 176 | |
| 177 | message[ContextMetadataKey] = { |
| 178 | remoteAddress: this.clientAddress, |
| 179 | } as ContextMetadata |
| 180 | |
| 181 | messageHandler = this.createMessageHandler([message, this]) as IMessageHandler & IAbortable |
| 182 | if (!messageHandler) { |
| 183 | logger.error('web-socket-adapter: unhandled message: no handler found:', message) |
| 184 | return |
| 185 | } |
| 186 | |
| 187 | abortable = typeof messageHandler.abort === 'function' |
| 188 | |
| 189 | if (abortable) { |
| 190 | const handlers = abortableMessageHandlers.get(this.client) ?? [] |
| 191 | handlers.push(messageHandler) |
| 192 | abortableMessageHandlers.set(this.client, handlers) |
| 193 | } |
| 194 | |
| 195 | await messageHandler.handleMessage(message) |
| 196 | } catch (error) { |
| 197 | if (error instanceof Error) { |
| 198 | if (error.name === 'AbortError') { |
| 199 | logger.error(`web-socket-adapter: abort from client ${this.clientId} (${this.getClientAddress()})`) |
| 200 | } else if (error.name === 'SyntaxError' || error instanceof ZodError) { |
| 201 | logger('invalid message client %s (%s): %s', this.clientId, this.getClientAddress(), error.message) |
| 202 | const notice = |
| 203 | error instanceof ZodError |
| 204 | ? `invalid: ${error.issues[0]?.message ?? error.message}` |
| 205 | : `invalid: ${error.message}` |
| 206 | this.sendMessage(createNoticeMessage(notice)) |
| 207 | } else { |
| 208 | logger.error('web-socket-adapter: unable to handle message:', error) |
| 209 | } |
| 210 | } else { |
| 211 | logger.error('web-socket-adapter: unable to handle message:', error) |
| 212 | } |
| 213 | } finally { |
| 214 | if (abortable && messageHandler) { |
| 215 | const handlers = abortableMessageHandlers.get(this.client) |
| 216 | if (handlers) { |
| 217 | const index = handlers.indexOf(messageHandler) |
| 218 | if (index >= 0) { |
| 219 | handlers.splice(index, 1) |
| 220 | } |
| 221 | } |
| 222 | } |
nothing calls this directly
no test coverage detected