aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/connection.cpp56
-rw-r--r--lib/jobs/basejob.cpp3
-rw-r--r--lib/jobs/basejob.h1
3 files changed, 43 insertions, 17 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp
index a7eae30f..5bf89815 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -110,6 +110,7 @@ class Connection::Private
void connectWithToken(const QString& user, const QString& accessToken,
const QString& deviceId);
+ void removeRoom(const QString& roomId);
template <typename EventT>
EventT* unpackAccountData() const
@@ -790,29 +791,36 @@ ForgetRoomJob* Connection::forgetRoom(const QString& id)
if (room && room->joinState() != JoinState::Leave)
{
auto leaveJob = room->leaveRoom();
- connect(leaveJob, &BaseJob::success, this, [this, forgetJob, room] {
- forgetJob->start(connectionData());
- // If the matching /sync response hasn't arrived yet, mark the room
- // for explicit deletion
- if (room->joinState() != JoinState::Leave)
- d->roomIdsToForget.push_back(room->id());
+ connect(leaveJob, &BaseJob::result, this, [this, leaveJob, forgetJob, room] {
+ // After leave, continue if there is no error or the room id is not found (IncorrectRequestError)
+ if(!leaveJob->error() || leaveJob->error() == BaseJob::StatusCode::UnknownObjectError) {
+ forgetJob->start(connectionData());
+ // If the matching /sync response hasn't arrived yet, mark the room
+ // for explicit deletion
+ if (room->joinState() != JoinState::Leave)
+ d->roomIdsToForget.push_back(room->id());
+ } else {
+ qCWarning(MAIN) << "Error leaving room "
+ << room->name() << ":"
+ << leaveJob->errorString();
+ forgetJob->abandon();
+ }
});
connect(leaveJob, &BaseJob::failure, forgetJob, &BaseJob::abandon);
}
else
forgetJob->start(connectionData());
- connect(forgetJob, &BaseJob::success, this, [this, id]
+ connect(forgetJob, &BaseJob::result, this, [this, id, forgetJob]
{
- // Delete whatever instances of the room are still in the map.
- for (auto f: {false, true})
- if (auto r = d->roomMap.take({ id, f }))
- {
- qCDebug(MAIN) << "Room" << r->objectName()
- << "in state" << toCString(r->joinState())
- << "will be deleted";
- emit r->beforeDestruction(r);
- r->deleteLater();
- }
+ // Leave room in case of success, or room not known by server
+ if(!forgetJob->error() || forgetJob->error() == BaseJob::StatusCode::IncorrectRequestError || forgetJob->error() == BaseJob::StatusCode::UnknownObjectError) {
+ // Delete the room from roomMap
+ d->removeRoom(id);
+ } else {
+ qCWarning(MAIN) << "Error forgetting room "
+ << id << ":"
+ << forgetJob->errorString();
+ }
});
return forgetJob;
}
@@ -1056,6 +1064,20 @@ Connection::DirectChatsMap Connection::directChats() const
return d->directChats;
}
+// Removes room with given id from roomMap
+void Connection::Private::removeRoom(const QString& roomId)
+{
+ for (auto f: {false, true})
+ if (auto r = roomMap.take({ roomId, f }))
+ {
+ qCDebug(MAIN) << "Room" << r->objectName()
+ << "in state" << toCString(r->joinState())
+ << "will be deleted";
+ emit r->beforeDestruction(r);
+ r->deleteLater();
+ }
+}
+
void Connection::addToDirectChats(const Room* room, User* user)
{
Q_ASSERT(room != nullptr && user != nullptr);
diff --git a/lib/jobs/basejob.cpp b/lib/jobs/basejob.cpp
index 0d9b9f10..97b5a904 100644
--- a/lib/jobs/basejob.cpp
+++ b/lib/jobs/basejob.cpp
@@ -325,6 +325,9 @@ void BaseJob::gotReply()
d->status.code = UserConsentRequiredError;
d->errorUrl = json.value("consent_uri"_ls).toString();
}
+ else if (errCode == "M_UNKNOWN") {
+ d->status.code = UnknownObjectError;
+ }
else if (errCode == "M_UNSUPPORTED_ROOM_VERSION" ||
errCode == "M_INCOMPATIBLE_ROOM_VERSION")
{
diff --git a/lib/jobs/basejob.h b/lib/jobs/basejob.h
index 4c1c7706..c1747cca 100644
--- a/lib/jobs/basejob.h
+++ b/lib/jobs/basejob.h
@@ -67,6 +67,7 @@ namespace QMatrixClient
, UnsupportedRoomVersionError
, NetworkAuthRequiredError
, UserConsentRequiredError
+ , UnknownObjectError // Unknown room or other item (M_UNKNOWN)
, UserDefinedError = 200
};