[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
    }
    


  • @mchinand

    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()) );
        }
    
    }

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.