diff --git a/src/connection.cpp b/src/connection.cpp index 13862eb..ae7151f 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -71,7 +71,21 @@ void ConnectionLoader::loadConnection() void ConnectionLoader::loadProgress() { - QTimer::singleShot(1, [=]() { this->ShowProgress(); }); + bool failed = false; + QTimer::singleShot(1, [=]() mutable { + // continually retry ShowProgress() until it succeeds + // by running without an exception + do { + try { + this->ShowProgress(); + failed = false; + } catch (const std::exception& e) { + DEBUG("caught exception " << e.what() ); + failed = true; + } + } while (failed); + + }); if (!Settings::getInstance()->isHeadless()) d->exec(); } @@ -85,7 +99,7 @@ void ConnectionLoader::ShowProgress() auto connection = makeConnection(config); auto me = this; - qDebug() << __func__ << ": server=" << config->server << " connection=" << connection << " me=" << me; + DEBUG("server=" << config->server << " connection=" << connection << " me=" << me); isSyncing = new QAtomicInteger(); isSyncing->store(true); @@ -101,39 +115,42 @@ void ConnectionLoader::ShowProgress() // When sync is done, set the connection this->doRPCSetConnectionShield(connection); }); - + // While it is syncing, we'll show the status updates while it is alive. QObject::connect(syncTimer, &QTimer::timeout, [=]() { // Check the sync status if (isSyncing != nullptr && isSyncing->load()) { // Get the sync status - try { - connection->doRPC("syncstatus", "", [=](json reply) { - if (isSyncing != nullptr && reply.find("synced_blocks") != reply.end()) - - { - qint64 synced = reply["synced_blocks"].get(); - qint64 total = reply["total_blocks"].get(); - me->showInformation( - "Syncing... " + QString::number(synced) + " / " + QString::number(total) - ); - } - }, - [=](QString err) { - qDebug() << "Sync error" << err; - }); - }catch (...) - { - main->logger->write("catch sync progress reply"); - } - + connection->doRPC("syncstatus", "", [=](json reply) { + if (isSyncing != nullptr && reply.find("synced_blocks") != reply.end()) { + qint64 synced = reply["synced_blocks"].get(); + qint64 total = reply["total_blocks"].get(); + me->showInformation( + "Syncing... " + QString::number(synced) + " / " + QString::number(total) + ); + } + }, [=](QString err) { + DEBUG("Sync error " << err); + // We may have gotten "Unexpected compression flag: 60" + // or some other error, so let's try another server + config->server = Settings::getRandomServer(); + DEBUG("Changed server to " << config->server ); + }); + } catch (const std::exception& e) { + DEBUG("syncstatus exception: " << e.what() ); + main->logger->write("catch sync progress reply"); + + // rethrow exception so loadProgress can catch + // it and retry the entire ShowProgress() function again + throw new std::runtime_error(std::string("syncstatus failed")); + } } -}); + }); -syncTimer->setInterval(1* 1000); -syncTimer->start(); -main->logger->write("Start sync timer"); + syncTimer->setInterval(1*1000); + syncTimer->start(); + main->logger->write("Start sync timer"); } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 2dc18be..ac798c6 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1095,10 +1095,10 @@ void MainWindow::payhushURI(QString uri, QString myAddr) { // Save the wallet this->getRPC()->saveWallet([=] (auto) { // Then reload the connection. The ConnectionLoader deletes itself. - auto cl = new ConnectionLoader(this, rpc); + auto cl = new ConnectionLoader(this, rpc); cl->loadProgress(); - }); - }); + }); + }); }else if ((pui.rescan->isChecked() == true) && (pui.privKeyTxt->toPlainText().startsWith("secret"))){