diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-11-14 16:19:58 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-11-19 08:48:39 +0900 |
commit | bdd0b841c48b42915087fde8d86e86e01631c627 (patch) | |
tree | 77f5d711c5a6d603e746fcb0b0d79c7d5c93da5f | |
parent | 62ec908efc0ea2390920d319c51984f51ce450bd (diff) | |
download | libquotient-bdd0b841c48b42915087fde8d86e86e01631c627.tar.gz libquotient-bdd0b841c48b42915087fde8d86e86e01631c627.zip |
Room: ensure proper error signalling on event sending failures
-rw-r--r-- | lib/room.cpp | 94 |
1 files changed, 52 insertions, 42 deletions
diff --git a/lib/room.cpp b/lib/room.cpp index 5e8833a8..2cbc8fc1 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -215,6 +215,8 @@ class Room::Private QString doSendEvent(const RoomEvent* pEvent); PendingEvents::iterator findAsPending(const RoomEvent* rawEvtPtr); + void onEventSendingFailure(const RoomEvent* pEvent, + const QString& txnId, BaseJob* call = nullptr); template <typename EvT> auto requestSetState(const QString& stateKey, const EvT& event) @@ -1154,49 +1156,41 @@ QString Room::Private::doSendEvent(const RoomEvent* pEvent) { auto txnId = pEvent->transactionId(); // TODO, #133: Enqueue the job rather than immediately trigger it. - auto call = connection->callApi<SendMessageJob>(BackgroundRequest, - id, pEvent->matrixType(), txnId, pEvent->contentJson()); - Room::connect(call, &BaseJob::started, q, - [this,pEvent,txnId] { - auto it = findAsPending(pEvent); - if (it == unsyncedEvents.end()) - { - qWarning(EVENTS) << "Pending event for transaction" << txnId - << "not found - got synced so soon?"; - return; - } - it->setDeparted(); - emit q->pendingEventChanged(it - unsyncedEvents.begin()); - }); - Room::connect(call, &BaseJob::failure, q, - [this,pEvent,txnId,call] { - auto it = findAsPending(pEvent); - if (it == unsyncedEvents.end()) - { - qCritical(EVENTS) << "Pending event for transaction" << txnId - << "got lost without successful sending"; - return; - } - it->setSendingFailed( - call->statusCaption() % ": " % call->errorString()); - emit q->pendingEventChanged(it - unsyncedEvents.begin()); - - }); - Room::connect(call, &BaseJob::success, q, - [this,call,pEvent,txnId] { - // Find an event by the pointer saved in the lambda (the pointer - // may be dangling by now but we can still search by it). - auto it = findAsPending(pEvent); - if (it == unsyncedEvents.end()) - { - qDebug(EVENTS) << "Pending event for transaction" << txnId - << "already merged"; - return; - } + if (auto call = connection->callApi<SendMessageJob>(BackgroundRequest, + id, pEvent->matrixType(), txnId, pEvent->contentJson())) + { + Room::connect(call, &BaseJob::started, q, + [this,pEvent,txnId] { + auto it = findAsPending(pEvent); + if (it == unsyncedEvents.end()) + { + qWarning(EVENTS) << "Pending event for transaction" << txnId + << "not found - got synced so soon?"; + return; + } + it->setDeparted(); + emit q->pendingEventChanged(it - unsyncedEvents.begin()); + }); + Room::connect(call, &BaseJob::failure, q, + std::bind(&Room::Private::onEventSendingFailure, + this, pEvent, txnId, call)); + Room::connect(call, &BaseJob::success, q, + [this,call,pEvent,txnId] { + // Find an event by the pointer saved in the lambda (the pointer + // may be dangling by now but we can still search by it). + auto it = findAsPending(pEvent); + if (it == unsyncedEvents.end()) + { + qDebug(EVENTS) << "Pending event for transaction" << txnId + << "already merged"; + return; + } - it->setReachedServer(call->eventId()); - emit q->pendingEventChanged(it - unsyncedEvents.begin()); - }); + it->setReachedServer(call->eventId()); + emit q->pendingEventChanged(it - unsyncedEvents.begin()); + }); + } else + onEventSendingFailure(pEvent, txnId); return txnId; } @@ -1209,6 +1203,22 @@ Room::PendingEvents::iterator Room::Private::findAsPending( return std::find_if(unsyncedEvents.begin(), unsyncedEvents.end(), comp); } +void Room::Private::onEventSendingFailure(const RoomEvent* pEvent, + const QString& txnId, BaseJob* call) +{ + auto it = findAsPending(pEvent); + if (it == unsyncedEvents.end()) + { + qCritical(EVENTS) << "Pending event for transaction" << txnId + << "could not be sent"; + return; + } + it->setSendingFailed(call + ? call->statusCaption() % ": " % call->errorString() + : tr("The call could not be started")); + emit q->pendingEventChanged(it - unsyncedEvents.begin()); +} + QString Room::retryMessage(const QString& txnId) { auto it = std::find_if(d->unsyncedEvents.begin(), d->unsyncedEvents.end(), |