fix(errors): surface previously-silent async failures (DP1/DP4/DP6)

Several fire-and-forget promises failed silently:
- RoomInput slash-command exe() rejections reset the editor as if they
  succeeded; now caught and shown via an error toast.
- Favourite / low-priority room-tag toggles (setRoomTag/deleteRoomTag)
  swallowed rejections; now surfaced via the same error toast.
- Call-decline sendEvent(RTCDecline) was uncaught; now logged best-effort
  while the local UI still dismisses.

Adds a shared createErrorToast builder mirroring createDownloadToast.
/kick and /ban route through rateLimitedActions, whose to() helper
swallows non-429 errors, so those two can still resolve on failure — noted
in code; the top-level exe() catch covers everything that does reject.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 22:29:39 -04:00
parent 2614e6b92d
commit 8eb961b682
5 changed files with 66 additions and 10 deletions
+8 -2
View File
@@ -291,7 +291,11 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => {
});
}
rateLimitedActions(users, (id) => mx.kick(room.roomId, id, reason));
// NOTE: rateLimitedActions' to() helper (utils/matrix.ts) swallows every
// non-429 error, so a failed kick (e.g. insufficient power level) resolves
// silently here — the RoomInput exe() catch cannot surface it. Propagating
// would require refactoring rateLimitedActions' shared error handling.
await rateLimitedActions(users, (id) => mx.kick(room.roomId, id, reason));
},
},
[Command.Ban]: {
@@ -313,7 +317,9 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => {
});
}
rateLimitedActions(users, (id) => mx.ban(room.roomId, id, reason));
// See the /kick note: rateLimitedActions swallows non-429 errors, so a
// failed ban resolves silently and can't be surfaced by the exe() catch.
await rateLimitedActions(users, (id) => mx.ban(room.roomId, id, reason));
},
},
[Command.UnBan]: {