aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2018-11-14 16:19:58 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2018-11-19 08:48:39 +0900
commitbdd0b841c48b42915087fde8d86e86e01631c627 (patch)
tree77f5d711c5a6d603e746fcb0b0d79c7d5c93da5f
parent62ec908efc0ea2390920d319c51984f51ce450bd (diff)
downloadlibquotient-bdd0b841c48b42915087fde8d86e86e01631c627.tar.gz
libquotient-bdd0b841c48b42915087fde8d86e86e01631c627.zip
Room: ensure proper error signalling on event sending failures
-rw-r--r--lib/room.cpp94
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(),