From 96c398ce748089383b4fe3f8d164cb97948c28f3 Mon Sep 17 00:00:00 2001 From: Justin Carlson Date: Mon, 5 Jun 2023 12:25:19 -0400 Subject: [PATCH] Fix crash from exceptions in handlers (#771) * Fix crash from exceptions in handlers * Fix withScope usage * Add changelog --- changelog.d/771.bugfix | 1 + src/Bridge.ts | 36 +++++++++++++++++++----------------- 2 files changed, 20 insertions(+), 17 deletions(-) create mode 100644 changelog.d/771.bugfix diff --git a/changelog.d/771.bugfix b/changelog.d/771.bugfix new file mode 100644 index 00000000..c71e8eee --- /dev/null +++ b/changelog.d/771.bugfix @@ -0,0 +1 @@ +Fix crash when failing to handle events, typically due to lacking permissions to send messages in a room. diff --git a/src/Bridge.ts b/src/Bridge.ts index 39a02669..89537659 100644 --- a/src/Bridge.ts +++ b/src/Bridge.ts @@ -786,22 +786,24 @@ export class Bridge { this.ready = true; } - private handleHookshotEvent(msg: MessageQueueMessageOut, connection: ConnType, handler: (c: ConnType, data: EventType) => Promise|unknown) { - Sentry.withScope((scope) => { - scope.setTransactionName('handleHookshotEvent'); - scope.setTags({ - eventType: msg.eventName, - roomId: connection.roomId, - }); - scope.setContext("connection", { - id: connection.connectionId, - }); - new Promise(() => handler(connection, msg.data)).catch((ex) => { - Sentry.captureException(ex, scope); + private async handleHookshotEvent(msg: MessageQueueMessageOut, connection: ConnType, handler: (c: ConnType, data: EventType) => Promise|unknown) { + try { + await handler(connection, msg.data); + } catch (e) { + Sentry.withScope((scope) => { + scope.setTransactionName('handleHookshotEvent'); + scope.setTags({ + eventType: msg.eventName, + roomId: connection.roomId, + }); + scope.setContext("connection", { + id: connection.connectionId, + }); + log.warn(`Connection ${connection.toString()} failed to handle ${msg.eventName}:`, e); Metrics.connectionsEventFailed.inc({ event: msg.eventName, connectionId: connection.connectionId }); - log.warn(`Connection ${connection.toString()} failed to handle ${msg.eventName}:`, ex); + Sentry.captureException(e, scope); }); - }); + } } private async bindHandlerToQueue(event: string, connectionFetcher: (data: EventType) => ConnType[], handler: (c: ConnType, data: EventType) => Promise|unknown) { @@ -810,8 +812,8 @@ export class Bridge { const connections = connectionFetcherBound(msg.data); log.debug(`${event} for ${connections.map(c => c.toString()).join(', ') || '[empty]'}`); connections.forEach((connection) => { - this.handleHookshotEvent(msg, connection, handler); - }) + void this.handleHookshotEvent(msg, connection, handler); + }); }); } @@ -1167,7 +1169,7 @@ export class Bridge { } for (const connection of this.connectionManager.getAllConnectionsForRoom(roomId)) { - if (!connection.onEvent) { + if (!connection.onEvent) { continue; } const scope = new Sentry.Scope();