[Client] Fix spurious server room join error (#7259)

* [Client] Fix spurious server room join error

The server replies RespContextError when a join command is received for a
room that connection is already registered in. The client was sending such
duplicate joins in benign situations - double-clicking to join a room, or
clicking a room the selector was already auto-joining - and answered them
with a modal telling users to restart the client.

Joins for the same room are now deduplicated while one is in flight, and a
remaining RespContextError is healed by leaving and rejoining the room so
the tab appears without a client restart. Error dialogs are only shown for
user-initiated joins, so failed auto-joins no longer spam critical popups.

* [Client] Bound stale-membership room join heal to one attempt

The RespContextError heal (leave + rejoin) previously recurred
unconditionally, so a server that kept returning RespContextError for a
reason other than stale membership would loop forever. Track room ids
that already received a heal and surface the error dialog after one
attempt instead of retrying indefinitely.

* [Client] Scope room-join heal guard to one join attempt

* [Client] Hoist room-join heal guard lookup out of response switch

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2026-09-19 09:56:09 +02:00 committed by GitHub
parent 59dd052143
commit 9acb9739b2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 88 additions and 28 deletions

View file

@ -10,6 +10,8 @@
#include "tab.h"
#include <QGroupBox>
#include <QHash>
#include <QSet>
#include <QTextBrowser>
#include <QTreeWidget>
@ -58,10 +60,17 @@ private slots:
int roomId);
private:
void leaveAndRejoinRoom(int roomId, bool setCurrent);
AbstractClient *client;
RoomSelector *roomSelector;
QTextBrowser *serverInfoBox;
bool shouldEmitUpdate = false;
/** Room ids with a join command in flight, mapped to whether the tab should be focused once it opens. */
QHash<int, bool> pendingRoomJoins;
/** Room ids for which a stale-membership heal (leave + rejoin) is currently in flight. Released as soon as the
* rejoin has been answered, so a heal is attempted at most once per join. */
QSet<int> healedRoomJoins;
public:
TabServer(TabSupervisor *_tabSupervisor, AbstractClient *_client);