[SOLVED] QNetworkReply - Retrying request gracefully
-
I'm using quite a lot of QNetworkReply to retrieve important data for the execution of my software.
In case the Request fail, I would like to try it again until it succeed
The QNetworkReply documentation says that finished should trigger even if an error occurred, quote on the error signal "This signal is emitted when the reply detects an error in processing. The finished() signal will probably follow, indicating that the connection is over"can someone confirm this? I don't like the "probably follow" I want to be sure that my data is retrieved. I would like to redo the request again if I detect it failed (no data was retrieved from the request). I want to make sure that finished() is called no matter what so I can retry it again in my slot.
Code example :
// Retrieve achievement list from DB replyGetListAchievement = AchievementDAO::getLstAchievement(); connect(replyGetListAchievement, SIGNAL(finished()), this, SLOT(slotGetAchievementListFinished()) );
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ManagerAchievement::slotGetAchievementListFinished() {QByteArray arrayData = replyGetListAchievement->readAll(); QString replyMsg(arrayData); lstAchievement = Util::parseJsonAchievementList(replyMsg); //request had a problem (should have data) - Redo request if (lstAchievement.size() < 1) { replyGetListAchievement = AchievementDAO::getLstAchievement(); connect(replyGetListAchievement, SIGNAL(finished()), this, SLOT(slotGetAchievementListFinished()) ); } else { replyGetListAchievementForUser = AchievementDAO::getLstAchievementForUser(account->id); connect(replyGetListAchievementForUser, SIGNAL(finished()), this, SLOT(slotGetAchievementListForUserFinished()) ); replyGetListAchievement->deleteLater(); } }
-
You should check if there was an error or not with QNetworkReply->error():
if (replyGetListAchievement->error() == QNetworkReply::NoError) { //success, process data } else { qDebug() << "Failure" << replyGetListAchievement->errorString(); // emit signal about error and possibly retry }
-
You should check if there was an error or not with QNetworkReply->error():
if (replyGetListAchievement->error() == QNetworkReply::NoError) { //success, process data } else { qDebug() << "Failure" << replyGetListAchievement->errorString(); // emit signal about error and possibly retry }
Thanks a lot, that is exactly what I wanted to do (avoiding to code another slot to catch the Error signal) didn't know you could check it like this after finished() was emitted.
void ManagerAchievement::slotGetAchievementListFinished() { //success, process data if (replyGetListAchievement->error() == QNetworkReply::NoError) { qDebug() << "no error process data achievement list!"; QByteArray arrayData = replyGetListAchievement->readAll(); QString replyMsg(arrayData); lstAchievement = Util::parseJsonAchievementList(replyMsg); qDebug() << "slotGetAchievementListFinished" << lstAchievement.size(); replyGetListAchievement->deleteLater(); replyGetListAchievementForUser = AchievementDAO::getLstAchievementForUser(account->id); connect(replyGetListAchievementForUser, SIGNAL(finished()), this, SLOT(slotGetAchievementListForUserFinished()) ); } // error, retry request else { qDebug() << "Problem getting achievement list! retry again..." << replyGetListAchievement->errorString(); replyGetListAchievement = AchievementDAO::getLstAchievement(); connect(replyGetListAchievement, SIGNAL(finished()), this, SLOT(slotGetAchievementListFinished()) ); } }