aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jobs/basejob.cpp76
-rw-r--r--jobs/basejob.h101
-rw-r--r--jobs/checkauthmethods.cpp2
-rw-r--r--jobs/checkauthmethods.h2
-rw-r--r--jobs/joinroomjob.cpp15
-rw-r--r--jobs/joinroomjob.h2
-rw-r--r--jobs/mediathumbnailjob.cpp4
-rw-r--r--jobs/mediathumbnailjob.h2
-rw-r--r--jobs/passwordlogin.cpp6
-rw-r--r--jobs/passwordlogin.h2
-rw-r--r--jobs/postmessagejob.cpp15
-rw-r--r--jobs/postmessagejob.h2
-rw-r--r--jobs/roommembersjob.cpp7
-rw-r--r--jobs/roommembersjob.h4
-rw-r--r--jobs/roommessagesjob.cpp4
-rw-r--r--jobs/roommessagesjob.h2
-rw-r--r--jobs/syncjob.cpp5
-rw-r--r--jobs/syncjob.h2
18 files changed, 118 insertions, 135 deletions
diff --git a/jobs/basejob.cpp b/jobs/basejob.cpp
index 9ab43087..3a0e1d3f 100644
--- a/jobs/basejob.cpp
+++ b/jobs/basejob.cpp
@@ -42,16 +42,16 @@ class BaseJob::Private
{
public:
Private(ConnectionData* c, JobHttpType t, bool nt)
- : connection(c), reply(nullptr), type(t), needsToken(nt), errorCode(NoError)
+ : connection(c), type(t), needsToken(nt)
+ , reply(nullptr), status(NoError)
{}
ConnectionData* connection;
- QScopedPointer<QNetworkReply, NetworkReplyDeleter> reply;
JobHttpType type;
bool needsToken;
- int errorCode;
- QString errorText;
+ QScopedPointer<QNetworkReply, NetworkReplyDeleter> reply;
+ Status status;
};
BaseJob::BaseJob(ConnectionData* connection, JobHttpType type, QString name, bool needsToken)
@@ -117,47 +117,45 @@ void BaseJob::start()
void BaseJob::gotReply()
{
- if (checkReply(d->reply.data()))
- parseReply(d->reply->readAll());
- // FIXME: we should not hold parseReply()/parseJson() responsible for
- // emitting the result; it should be done here instead.
+ setStatus(checkReply(d->reply.data()));
+ if (status().good())
+ setStatus(parseReply(d->reply->readAll()));
+
+ finishJob(true);
}
-bool BaseJob::checkReply(QNetworkReply* reply)
+BaseJob::Status BaseJob::checkReply(QNetworkReply* reply) const
{
switch( reply->error() )
{
case QNetworkReply::NoError:
- return true;
+ return NoError;
case QNetworkReply::AuthenticationRequiredError:
case QNetworkReply::ContentAccessDenied:
case QNetworkReply::ContentOperationNotPermittedError:
qDebug() << "Content access error, Qt error code:" << reply->error();
- fail( ContentAccessError, reply->errorString() );
- return false;
+ return { ContentAccessError, reply->errorString() };
default:
qDebug() << "NetworkError, Qt error code:" << reply->error();
- fail( NetworkError, reply->errorString() );
- return false;
+ return { NetworkError, reply->errorString() };
}
}
-void BaseJob::parseReply(QByteArray data)
+BaseJob::Status BaseJob::parseReply(QByteArray data)
{
QJsonParseError error;
QJsonDocument json = QJsonDocument::fromJson(data, &error);
if( error.error == QJsonParseError::NoError )
- parseJson(json);
+ return parseJson(json);
else
- fail( JsonParseError, error.errorString() );
+ return { JsonParseError, error.errorString() };
}
-void BaseJob::parseJson(const QJsonDocument&)
+BaseJob::Status BaseJob::parseJson(const QJsonDocument&)
{
- // Do nothing by default
- emitResult();
+ return Success;
}
void BaseJob::finishJob(bool emitResult)
@@ -165,7 +163,7 @@ void BaseJob::finishJob(bool emitResult)
if (!d->reply)
{
qWarning() << objectName()
- << ": empty network reply (finish() called more than once?)";
+ << ": empty network reply (finishJob() called more than once?)";
return;
}
@@ -184,29 +182,34 @@ void BaseJob::finishJob(bool emitResult)
deleteLater();
}
-int BaseJob::error() const
+BaseJob::Status BaseJob::status() const
{
- return d->errorCode;
+ return d->status;
}
-QString BaseJob::errorString() const
+int BaseJob::error() const
{
- return d->errorText;
+ return d->status.code;
}
-void BaseJob::setError(int errorCode)
+QString BaseJob::errorString() const
{
- d->errorCode = errorCode;
+ return d->status.message;
}
-void BaseJob::setErrorText(QString errorText)
+void BaseJob::setStatus(Status s)
{
- d->errorText = errorText;
+ d->status = s;
+ if (!s.good())
+ {
+ qWarning() << QString("Job %1 status: %2, code %3")
+ .arg(objectName()).arg(s.message).arg(s.code);
+ }
}
-void BaseJob::emitResult()
+void BaseJob::setStatus(int code, QString message)
{
- finishJob(true);
+ setStatus({ code, message });
}
void BaseJob::abandon()
@@ -214,17 +217,10 @@ void BaseJob::abandon()
finishJob(false);
}
-void BaseJob::fail(int errorCode, QString errorString)
-{
- setError( errorCode );
- setErrorText( errorString );
- qWarning() << "Job" << objectName() << "failed:" << errorString;
- emitResult();
-}
-
void BaseJob::timeout()
{
- fail( TimeoutError, "The job has timed out" );
+ setStatus( TimeoutError, "The job has timed out" );
+ finishJob(true);
}
void BaseJob::sslErrors(const QList<QSslError>& errors)
diff --git a/jobs/basejob.h b/jobs/basejob.h
index 8e17e18e..07b1f1dd 100644
--- a/jobs/basejob.h
+++ b/jobs/basejob.h
@@ -40,10 +40,38 @@ namespace QMatrixClient
public:
/* Just in case, the values are compatible with KJob
* (which BaseJob used to inherit from). */
- enum ErrorCode { NoError = 0, NetworkError = 100,
- JsonParseError, TimeoutError, ContentAccessError,
- UserDefinedError = 512 };
+ enum StatusCode { NoError = 0 // To be compatible with Qt conventions
+ , Success = 0
+ , ErrorLevel = 100 // Errors have codes starting from this
+ , NetworkError = 100
+ , JsonParseError
+ , TimeoutError
+ , ContentAccessError
+ , UserDefinedError = 200
+ };
+ /**
+ * This structure stores the status of a server call job. The status consists
+ * of a code, that is described (but not delimited) by the respective enum,
+ * and a freeform message.
+ *
+ * To extend the list of error codes, define an (anonymous) enum
+ * along the lines of StatusCode, with additional values
+ * starting at UserDefinedError
+ */
+ class Status
+ {
+ public:
+ Status(StatusCode c) : code(c) { }
+ Status(int c, QString m) : code(c), message(m) { }
+
+ bool good() const { return code < ErrorLevel; }
+
+ int code;
+ QString message;
+ };
+
+ public:
BaseJob(ConnectionData* connection, JobHttpType type,
QString name, bool needsToken=true);
virtual ~BaseJob();
@@ -59,6 +87,7 @@ namespace QMatrixClient
*/
void abandon();
+ Status status() const;
int error() const;
virtual QString errorString() const;
@@ -115,74 +144,40 @@ namespace QMatrixClient
virtual QJsonObject data() const;
/**
- * Checks the received reply for sanity; calls setError/setErrorText
- * respectively. setError() with any argument except NoError prevents
- * further parseReply()/parseJson() invocations.
+ * Used by gotReply() slot to check the received reply for general
+ * issues such as network errors or access denial.
+ * Returning anything except NoError/Success prevents
+ * further parseReply()/parseJson() invocation.
*
* @param reply the reply received from the server
+ * @return the result of checking the reply
+ *
+ * @see gotReply
*/
- virtual bool checkReply(QNetworkReply* reply);
+ virtual Status checkReply(QNetworkReply* reply) const;
/**
* Processes the reply. By default, parses the reply into
* a QJsonDocument and calls parseJson() if it's a valid JSON.
- * Overrides MUST ensure that fail() or emitResult() is called
- * on every execution path exactly once.
*
* @param data raw contents of a HTTP reply from the server (without headers)
+ *
+ * @see gotReply, parseJson
*/
- virtual void parseReply(QByteArray data);
+ virtual Status parseReply(QByteArray data);
/**
* Processes the JSON document received from the Matrix server.
- * By default emits a successful result without analysing the JSON.
- * Overrides MUST ensure that fail() or emitResult() is called
- * on every execution path exactly once.
+ * By default returns succesful status without analysing the JSON.
*
* @param json valid JSON document received from the server
- */
- virtual void parseJson(const QJsonDocument&);
-
- /**
- * Sets the error code.
*
- * It should be called when an error is encountered in the job,
- * just before calling emitResult(). Normally you might want to
- * use fail() instead - it sets error code, error text, makes sure
- * the job has finished and invokes emitResult after that.
- *
- * To extend the list of error codes, define an (anonymous) enum
- * with additional values starting at BaseJob::UserDefinedError
- *
- * @param errorCode the error code
- * @see emitResult(), fail()
- */
- void setError(int errorCode);
- /**
- * Sets the error text. Usually is combined with a setError() call
- * before it, as setErrorText() alone does not indicate the error status.
- */
- void setErrorText(QString errorText);
-
- /**
- * Emits the result signal, and suicides this job.
- * It first notifies the observers to hide the progress for this job
- * using the finished() signal.
- *
- * @note: Deletes this job using deleteLater().
- *
- * @see result()
- * @see finished()
- */
- void emitResult();
-
- /**
- * Same as emitResult() but calls setError() and setErrorText()
- * with respective arguments passed to it. Use it as a shortcut to
- * finish the job with a failure status.
+ * @see parseReply
*/
- void fail( int errorCode, QString errorString );
+ virtual Status parseJson(const QJsonDocument&);
+ void setStatus(Status s);
+ void setStatus(int code, QString message);
protected slots:
void timeout();
diff --git a/jobs/checkauthmethods.cpp b/jobs/checkauthmethods.cpp
index 55d8632a..f471c135 100644
--- a/jobs/checkauthmethods.cpp
+++ b/jobs/checkauthmethods.cpp
@@ -57,7 +57,7 @@ QString CheckAuthMethods::apiPath() const
return "_matrix/client/r0/login";
}
-void CheckAuthMethods::parseJson(const QJsonDocument& data)
+BaseJob::Status CheckAuthMethods::parseJson(const QJsonDocument& data)
{
// TODO
}
diff --git a/jobs/checkauthmethods.h b/jobs/checkauthmethods.h
index 2951e27f..36eaa01a 100644
--- a/jobs/checkauthmethods.h
+++ b/jobs/checkauthmethods.h
@@ -35,7 +35,7 @@ namespace QMatrixClient
protected:
QString apiPath() const override;
- void parseJson(const QJsonDocument& data) override;
+ Status parseJson(const QJsonDocument& data) override;
private:
class Private;
diff --git a/jobs/joinroomjob.cpp b/jobs/joinroomjob.cpp
index 799d4926..8848aa70 100644
--- a/jobs/joinroomjob.cpp
+++ b/jobs/joinroomjob.cpp
@@ -54,18 +54,15 @@ QString JoinRoomJob::apiPath() const
return QString("_matrix/client/r0/join/%1").arg(d->roomAlias);
}
-void JoinRoomJob::parseJson(const QJsonDocument& data)
+BaseJob::Status JoinRoomJob::parseJson(const QJsonDocument& data)
{
QJsonObject json = data.object();
- if( !json.contains("room_id") )
- {
- fail( BaseJob::UserDefinedError, "Something went wrong..." );
- qDebug() << data;
- return;
- }
- else
+ if( json.contains("room_id") )
{
d->roomId = json.value("room_id").toString();
+ return Success;
}
- emitResult();
+
+ qDebug() << data;
+ return { UserDefinedError, "No room_id in the JSON response" };
}
diff --git a/jobs/joinroomjob.h b/jobs/joinroomjob.h
index 1329ca56..a6f4af21 100644
--- a/jobs/joinroomjob.h
+++ b/jobs/joinroomjob.h
@@ -35,7 +35,7 @@ namespace QMatrixClient
protected:
QString apiPath() const override;
- void parseJson(const QJsonDocument& data) override;
+ Status parseJson(const QJsonDocument& data) override;
private:
class Private;
diff --git a/jobs/mediathumbnailjob.cpp b/jobs/mediathumbnailjob.cpp
index 3f5f9ebf..1e434fbc 100644
--- a/jobs/mediathumbnailjob.cpp
+++ b/jobs/mediathumbnailjob.cpp
@@ -70,11 +70,11 @@ QUrlQuery MediaThumbnailJob::query() const
return query;
}
-void MediaThumbnailJob::parseReply(QByteArray data)
+BaseJob::Status MediaThumbnailJob::parseReply(QByteArray data)
{
if( !d->thumbnail.loadFromData(data) )
{
qDebug() << "MediaThumbnailJob: could not read image data";
}
- emitResult();
+ return Success;
}
diff --git a/jobs/mediathumbnailjob.h b/jobs/mediathumbnailjob.h
index 1af8ecd4..3babf845 100644
--- a/jobs/mediathumbnailjob.h
+++ b/jobs/mediathumbnailjob.h
@@ -40,7 +40,7 @@ namespace QMatrixClient
QString apiPath() const override;
QUrlQuery query() const override;
- virtual void parseReply(QByteArray data) override;
+ Status parseReply(QByteArray data) override;
private:
class Private;
diff --git a/jobs/passwordlogin.cpp b/jobs/passwordlogin.cpp
index 231dcce5..c85e4c13 100644
--- a/jobs/passwordlogin.cpp
+++ b/jobs/passwordlogin.cpp
@@ -80,15 +80,15 @@ QJsonObject PasswordLogin::data() const
return json;
}
-void PasswordLogin::parseJson(const QJsonDocument& data)
+BaseJob::Status PasswordLogin::parseJson(const QJsonDocument& data)
{
QJsonObject json = data.object();
if( !json.contains("access_token") || !json.contains("home_server") || !json.contains("user_id") )
{
- fail( BaseJob::UserDefinedError, "Unexpected data" );
+ return { UserDefinedError, "No expected data" };
}
d->returned_token = json.value("access_token").toString();
d->returned_server = json.value("home_server").toString();
d->returned_id = json.value("user_id").toString();
- emitResult();
+ return Success;
}
diff --git a/jobs/passwordlogin.h b/jobs/passwordlogin.h
index 75a45cae..d7e42725 100644
--- a/jobs/passwordlogin.h
+++ b/jobs/passwordlogin.h
@@ -38,7 +38,7 @@ namespace QMatrixClient
protected:
QString apiPath() const override;
QJsonObject data() const override;
- void parseJson(const QJsonDocument& data) override;
+ Status parseJson(const QJsonDocument& data) override;
private:
class Private;
diff --git a/jobs/postmessagejob.cpp b/jobs/postmessagejob.cpp
index cf9b94fd..0a38da62 100644
--- a/jobs/postmessagejob.cpp
+++ b/jobs/postmessagejob.cpp
@@ -61,14 +61,11 @@ QJsonObject PostMessageJob::data() const
return json;
}
-void PostMessageJob::parseJson(const QJsonDocument& data)
+BaseJob::Status PostMessageJob::parseJson(const QJsonDocument& data)
{
- QJsonObject json = data.object();
- if( !json.contains("event_id") )
- {
- fail( BaseJob::UserDefinedError, "Something went wrong..." );
- qDebug() << data;
- return;
- }
- emitResult();
+ if( data.object().contains("event_id") )
+ return Success;
+
+ qDebug() << data;
+ return { UserDefinedError, "No event_id in the JSON response" };
}
diff --git a/jobs/postmessagejob.h b/jobs/postmessagejob.h
index 9d354240..73d72020 100644
--- a/jobs/postmessagejob.h
+++ b/jobs/postmessagejob.h
@@ -35,7 +35,7 @@ namespace QMatrixClient
protected:
QString apiPath() const override;
QJsonObject data() const override;
- void parseJson(const QJsonDocument& data) override;
+ Status parseJson(const QJsonDocument& data) override;
private:
class Private;
diff --git a/jobs/roommembersjob.cpp b/jobs/roommembersjob.cpp
index 002be75b..7fc44c63 100644
--- a/jobs/roommembersjob.cpp
+++ b/jobs/roommembersjob.cpp
@@ -56,10 +56,9 @@ QString RoomMembersJob::apiPath() const
return QString("_matrix/client/r0/rooms/%1/members").arg(d->room->id());
}
-void RoomMembersJob::parseJson(const QJsonDocument& data)
+BaseJob::Status RoomMembersJob::parseJson(const QJsonDocument& data)
{
- QJsonObject obj = data.object();
- QJsonArray chunk = obj.value("chunk").toArray();
+ QJsonArray chunk = data.object().value("chunk").toArray();
for( const QJsonValue& val : chunk )
{
State* state = State::fromJson(val.toObject());
@@ -67,5 +66,5 @@ void RoomMembersJob::parseJson(const QJsonDocument& data)
d->states.append(state);
}
qDebug() << "States: " << d->states.count();
- emitResult();
+ return Success;
}
diff --git a/jobs/roommembersjob.h b/jobs/roommembersjob.h
index ffae4309..04803d67 100644
--- a/jobs/roommembersjob.h
+++ b/jobs/roommembersjob.h
@@ -35,8 +35,8 @@ namespace QMatrixClient
QList<State*> states();
protected:
- virtual QString apiPath() const override;
- virtual void parseJson(const QJsonDocument& data) override;
+ QString apiPath() const override;
+ Status parseJson(const QJsonDocument& data) override;
private:
class Private;
diff --git a/jobs/roommessagesjob.cpp b/jobs/roommessagesjob.cpp
index f1943d2c..ba075007 100644
--- a/jobs/roommessagesjob.cpp
+++ b/jobs/roommessagesjob.cpp
@@ -81,10 +81,10 @@ QUrlQuery RoomMessagesJob::query() const
return query;
}
-void RoomMessagesJob::parseJson(const QJsonDocument& data)
+BaseJob::Status RoomMessagesJob::parseJson(const QJsonDocument& data)
{
QJsonObject obj = data.object();
d->events = eventListFromJson(obj.value("chunk").toArray());
d->end = obj.value("end").toString();
- emitResult();
+ return Success;
}
diff --git a/jobs/roommessagesjob.h b/jobs/roommessagesjob.h
index c068f235..52a72f70 100644
--- a/jobs/roommessagesjob.h
+++ b/jobs/roommessagesjob.h
@@ -40,7 +40,7 @@ namespace QMatrixClient
protected:
QString apiPath() const override;
QUrlQuery query() const override;
- void parseJson(const QJsonDocument& data) override;
+ Status parseJson(const QJsonDocument& data) override;
private:
class Private;
diff --git a/jobs/syncjob.cpp b/jobs/syncjob.cpp
index 3a7573bc..3bd1f0c8 100644
--- a/jobs/syncjob.cpp
+++ b/jobs/syncjob.cpp
@@ -110,7 +110,7 @@ QUrlQuery SyncJob::query() const
return query;
}
-void SyncJob::parseJson(const QJsonDocument& data)
+BaseJob::Status SyncJob::parseJson(const QJsonDocument& data)
{
QJsonObject json = data.object();
d->nextBatch = json.value("next_batch").toString();
@@ -134,8 +134,7 @@ void SyncJob::parseJson(const QJsonDocument& data)
}
}
- emitResult();
- qDebug() << objectName() << ": processing complete";
+ return Success;
}
void SyncRoomData::EventList::fromJson(const QJsonObject& roomContents)
diff --git a/jobs/syncjob.h b/jobs/syncjob.h
index 95d7aacb..51d07944 100644
--- a/jobs/syncjob.h
+++ b/jobs/syncjob.h
@@ -73,7 +73,7 @@ namespace QMatrixClient
protected:
QString apiPath() const override;
QUrlQuery query() const override;
- void parseJson(const QJsonDocument& data) override;
+ Status parseJson(const QJsonDocument& data) override;
private:
class Private;