From a0e41a11dec9e195455d990fd0e87390882c703d Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Mon, 14 Aug 2023 16:03:57 +0300 Subject: [PATCH] Display error message when unrecoverable error occurred PR #19462. --- src/app/application.cpp | 16 -------------- src/app/main.cpp | 33 ++++++++++++++++++++++++++--- src/base/bittorrent/sessionimpl.cpp | 12 +++++++++-- src/base/bittorrent/torrentimpl.cpp | 7 ++++++ 4 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/app/application.cpp b/src/app/application.cpp index 447a35c4f..ab58c1bb7 100644 --- a/src/app/application.cpp +++ b/src/app/application.cpp @@ -759,7 +759,6 @@ void Application::processParams(const QBtCommandLineParameters ¶ms) } int Application::exec() -try { #if !defined(DISABLE_WEBUI) && defined(DISABLE_GUI) const QString loadingStr = tr("WebUI will be started shortly after internal preparations. Please wait..."); @@ -928,21 +927,6 @@ try return BaseApplication::exec(); } -catch (const RuntimeError &err) -{ -#ifdef DISABLE_GUI - fprintf(stderr, "%s", qPrintable(err.message())); -#else - QMessageBox msgBox; - msgBox.setIcon(QMessageBox::Critical); - msgBox.setText(QCoreApplication::translate("Application", "Application failed to start.")); - msgBox.setInformativeText(err.message()); - msgBox.show(); // Need to be shown or to moveToCenter does not work - msgBox.move(Utils::Gui::screenCenter(&msgBox)); - msgBox.exec(); -#endif - return EXIT_FAILURE; -} bool Application::isRunning() { diff --git a/src/app/main.cpp b/src/app/main.cpp index 71ebb2160..fcd33212a 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -46,7 +46,7 @@ #endif #include -#include +#include #include #ifndef DISABLE_GUI @@ -86,6 +86,7 @@ using namespace std::chrono_literals; void displayVersion(); bool userAgreesWithLegalNotice(); void displayBadArgMessage(const QString &message); +void displayErrorMessage(const QString &message); #ifndef DISABLE_GUI void showSplashScreen(); @@ -105,10 +106,12 @@ int main(int argc, char *argv[]) // We must save it here because QApplication constructor may change it bool isOneArg = (argc == 2); + // `app` must be declared out of try block to allow display message box in case of exception + std::unique_ptr app; try { // Create Application - auto app = std::make_unique(argc, argv); + app = std::make_unique(argc, argv); #ifdef Q_OS_WIN // QCoreApplication::applicationDirPath() needs an Application object instantiated first @@ -255,7 +258,7 @@ int main(int argc, char *argv[]) } catch (const RuntimeError &er) { - qDebug() << er.message(); + displayErrorMessage(er.message()); return EXIT_FAILURE; } } @@ -298,6 +301,30 @@ void displayBadArgMessage(const QString &message) #endif } +void displayErrorMessage(const QString &message) +{ +#ifndef DISABLE_GUI + if (QApplication::instance()) + { + QMessageBox msgBox; + msgBox.setIcon(QMessageBox::Critical); + msgBox.setText(QCoreApplication::translate("Main", "An unrecoverable error occurred.")); + msgBox.setInformativeText(message); + msgBox.show(); // Need to be shown or to moveToCenter does not work + msgBox.move(Utils::Gui::screenCenter(&msgBox)); + msgBox.exec(); + } + else + { + const QString errMsg = QCoreApplication::translate("Main", "qBittorrent has encountered an unrecoverable error.") + u'\n' + message + u'\n'; + fprintf(stderr, "%s", qUtf8Printable(errMsg)); + } +#else + const QString errMsg = QCoreApplication::translate("Main", "qBittorrent has encountered an unrecoverable error.") + u'\n' + message + u'\n'; + fprintf(stderr, "%s", qUtf8Printable(errMsg)); +#endif +} + bool userAgreesWithLegalNotice() { Preferences *const pref = Preferences::instance(); diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index 6416c3b48..821f4ee06 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -3103,8 +3103,16 @@ void SessionImpl::generateResumeData() void SessionImpl::saveResumeData() { for (const TorrentImpl *torrent : asConst(m_torrents)) - torrent->nativeHandle().save_resume_data(lt::torrent_handle::only_if_modified); - m_numResumeData += m_torrents.size(); + { + // When the session is terminated due to unrecoverable error + // some of the torrent handles can be corrupted + try + { + torrent->nativeHandle().save_resume_data(lt::torrent_handle::only_if_modified); + ++m_numResumeData; + } + catch (const std::exception &) {} + } // clear queued storage move jobs except the current ongoing one if (m_moveStorageQueue.size() > 1) diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index f0fd9f414..2aa85e76a 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -50,6 +50,7 @@ #include #include +#include "base/exceptions.h" #include "base/global.h" #include "base/logger.h" #include "base/preferences.h" @@ -1696,6 +1697,7 @@ void TorrentImpl::endReceivedMetadataHandling(const Path &savePath, const PathLi } void TorrentImpl::reload() +try { m_completedFiles.fill(false); m_filesProgress.fill(0); @@ -1738,6 +1740,11 @@ void TorrentImpl::reload() updateState(); } +catch (const lt::system_error &err) +{ + throw RuntimeError(tr("Failed to reload torrent. Torrent: %1. Reason: %2") + .arg(id().toString(), QString::fromLocal8Bit(err.what()))); +} void TorrentImpl::pause() {