Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-apps-engine-post-event-unhandled-promises.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/apps-engine": patch
---

Fixed unhandled promise rejections in `AppListenerManager` for fire-and-forget post-event handlers (`IPostMessageSent`, `IPostSystemMessageSent`, `IPostMessageDeleted`, `IPostMessageUpdated`, `IPostRoomCreate`, `IPostRoomDeleted`, `IPostExternalComponentOpened`, `IPostExternalComponentClosed`). These async methods were called without `await` and without a rejection handler, which could cause `UnhandledPromiseRejection` errors (process-terminating in Node.js 15+) if an app threw inside a post-event hook. The fire-and-forget behavior is preserved — post events intentionally do not block the caller — but errors are now surfaced to the console.
16 changes: 8 additions & 8 deletions packages/apps-engine/src/server/managers/AppListenerManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,15 +357,15 @@ export class AppListenerManager {
case AppInterface.IPreMessageSentModify:
return this.executePreMessageSentModify(data as IMessage);
case AppInterface.IPostMessageSent:
this.executePostMessageSent(data as IMessage);
void this.executePostMessageSent(data as IMessage).catch(console.error);
return;
case AppInterface.IPostSystemMessageSent:
this.executePostSystemMessageSent(data as IMessage);
void this.executePostSystemMessageSent(data as IMessage).catch(console.error);
return;
case AppInterface.IPreMessageDeletePrevent:
return this.executePreMessageDeletePrevent(data as IMessage);
case AppInterface.IPostMessageDeleted:
this.executePostMessageDelete(data as IMessageDeleteContext);
void this.executePostMessageDelete(data as IMessageDeleteContext).catch(console.error);
return;
case AppInterface.IPreMessageUpdatedPrevent:
return this.executePreMessageUpdatedPrevent(data as IMessage);
Expand All @@ -374,7 +374,7 @@ export class AppListenerManager {
case AppInterface.IPreMessageUpdatedModify:
return this.executePreMessageUpdatedModify(data as IMessage);
case AppInterface.IPostMessageUpdated:
this.executePostMessageUpdated(data as IMessage);
void this.executePostMessageUpdated(data as IMessage).catch(console.error);
return;
case AppInterface.IPostMessageReacted:
return this.executePostMessageReacted(data as IMessageReactionContext);
Expand All @@ -394,12 +394,12 @@ export class AppListenerManager {
case AppInterface.IPreRoomCreateModify:
return this.executePreRoomCreateModify(data as IRoom);
case AppInterface.IPostRoomCreate:
this.executePostRoomCreate(data as IRoom);
void this.executePostRoomCreate(data as IRoom).catch(console.error);
return;
case AppInterface.IPreRoomDeletePrevent:
return this.executePreRoomDeletePrevent(data as IRoom);
case AppInterface.IPostRoomDeleted:
this.executePostRoomDeleted(data as IRoom);
void this.executePostRoomDeleted(data as IRoom).catch(console.error);
return;
case AppInterface.IPreRoomUserJoined:
return this.executePreRoomUserJoined(data as IRoomUserJoinedContext);
Expand All @@ -411,10 +411,10 @@ export class AppListenerManager {
return this.executePostRoomUserLeave(data as IRoomUserLeaveContext);
// External Components
case AppInterface.IPostExternalComponentOpened:
this.executePostExternalComponentOpened(data as IExternalComponent);
void this.executePostExternalComponentOpened(data as IExternalComponent).catch(console.error);
return;
case AppInterface.IPostExternalComponentClosed:
this.executePostExternalComponentClosed(data as IExternalComponent);
void this.executePostExternalComponentClosed(data as IExternalComponent).catch(console.error);
return;
case AppInterface.IUIKitInteractionHandler:
return this.executeUIKitInteraction(data as UIKitIncomingInteraction);
Expand Down