Display error message when unrecoverable error occurred

PR #19462.
This commit is contained in:
Vladimir Golovnev 2023-08-14 16:03:57 +03:00
parent 67d340ad63
commit 2a04a4d077
4 changed files with 47 additions and 21 deletions

View file

@ -763,7 +763,6 @@ void Application::processParams(const QBtCommandLineParameters &params)
} }
int Application::exec() int Application::exec()
try
{ {
#if !defined(DISABLE_WEBUI) && defined(DISABLE_GUI) #if !defined(DISABLE_WEBUI) && defined(DISABLE_GUI)
const QString loadingStr = tr("WebUI will be started shortly after internal preparations. Please wait..."); const QString loadingStr = tr("WebUI will be started shortly after internal preparations. Please wait...");
@ -932,21 +931,6 @@ try
return BaseApplication::exec(); 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() bool Application::isRunning()
{ {

View file

@ -46,7 +46,7 @@
#endif #endif
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug> #include <QString>
#include <QThread> #include <QThread>
#ifndef DISABLE_GUI #ifndef DISABLE_GUI
@ -86,6 +86,7 @@ using namespace std::chrono_literals;
void displayVersion(); void displayVersion();
bool userAgreesWithLegalNotice(); bool userAgreesWithLegalNotice();
void displayBadArgMessage(const QString &message); void displayBadArgMessage(const QString &message);
void displayErrorMessage(const QString &message);
#ifndef DISABLE_GUI #ifndef DISABLE_GUI
void showSplashScreen(); void showSplashScreen();
@ -114,10 +115,12 @@ int main(int argc, char *argv[])
Application::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); Application::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif #endif
// `app` must be declared out of try block to allow display message box in case of exception
std::unique_ptr<Application> app;
try try
{ {
// Create Application // Create Application
auto app = std::make_unique<Application>(argc, argv); app = std::make_unique<Application>(argc, argv);
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// QCoreApplication::applicationDirPath() needs an Application object instantiated first // QCoreApplication::applicationDirPath() needs an Application object instantiated first
@ -268,7 +271,7 @@ int main(int argc, char *argv[])
} }
catch (const RuntimeError &er) catch (const RuntimeError &er)
{ {
qDebug() << er.message(); displayErrorMessage(er.message());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
@ -311,6 +314,30 @@ void displayBadArgMessage(const QString &message)
#endif #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() bool userAgreesWithLegalNotice()
{ {
Preferences *const pref = Preferences::instance(); Preferences *const pref = Preferences::instance();

View file

@ -3143,8 +3143,16 @@ void SessionImpl::generateResumeData()
void SessionImpl::saveResumeData() void SessionImpl::saveResumeData()
{ {
for (const TorrentImpl *torrent : asConst(m_torrents)) 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 // clear queued storage move jobs except the current ongoing one
if (m_moveStorageQueue.size() > 1) if (m_moveStorageQueue.size() > 1)

View file

@ -51,6 +51,7 @@
#include <QStringList> #include <QStringList>
#include <QUrl> #include <QUrl>
#include "base/exceptions.h"
#include "base/global.h" #include "base/global.h"
#include "base/logger.h" #include "base/logger.h"
#include "base/preferences.h" #include "base/preferences.h"
@ -1701,6 +1702,7 @@ void TorrentImpl::endReceivedMetadataHandling(const Path &savePath, const PathLi
} }
void TorrentImpl::reload() void TorrentImpl::reload()
try
{ {
m_completedFiles.fill(false); m_completedFiles.fill(false);
m_filesProgress.fill(0); m_filesProgress.fill(0);
@ -1743,6 +1745,11 @@ void TorrentImpl::reload()
updateState(); 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() void TorrentImpl::pause()
{ {