Merge bitcoin-core/gui#379: Prompt to reset settings when settings.json cannot be read

1ee6d0b01a517893967379677029fb5417978247 gui: Prompt to reset settings when settings.json cannot be read (Russell Yanofsky)

Pull request description:

  Currently the GUI shows confusing error messages when `settings.json` can't be read or written on startup. This causes the unrecoverable read error described in bitcoin/bitcoin#21340 and write error described bitcoin/bitcoin#21974. Current error read message looks like:

  ![current](https://user-images.githubusercontent.com/7133040/124977362-638ffc80-dffe-11eb-9edd-89135a9bc602.png)

  This PR tries to clarify the error dialog, and adds an option to just clear the settings and reset them to default:

  ![new-read-error](https://user-images.githubusercontent.com/7133040/124977636-b669b400-dffe-11eb-8d35-02eda95f48c0.png)
  ![new-read-details](https://user-images.githubusercontent.com/7133040/124977644-bb2e6800-dffe-11eb-9209-11c1c3d7be40.png)

  Additionally the PR also shows a slightly better error message when there is an error trying to write the settings file. This error probably should occur less frequently, but it is easy to improve, and it should be good to make the write error consistent with the read error. The new write error dialog looks like:

  ![new-write-error](https://user-images.githubusercontent.com/7133040/124978016-3bed6400-dfff-11eb-9d79-9b2e9bbc4369.png)

  ![new-write-details](https://user-images.githubusercontent.com/7133040/124978025-3db72780-dfff-11eb-8df5-741f75a402d9.png)

ACKs for top commit:
  jarolrod:
    ACK 1ee6d0b01a517893967379677029fb5417978247
  Zero-1729:
    ACK 1ee6d0b01a517893967379677029fb5417978247
  hebasto:
    ACK 1ee6d0b01a517893967379677029fb5417978247, tested on Linux Mint 20.2 (Qt 5.12.8).

Tree-SHA512: fb57a0a0d032e3f8219fff49a4de69b4c962bf0b448544ccf9d8d4d45c5bd209e23653d4f13300b9e534b9c03de159498bef1658e95defe3ab6a8ecac57d592c
This commit is contained in:
Hennadii Stepanov 2021-08-06 18:39:59 +03:00 committed by pasta
parent 3b317db95f
commit 65b7ec3366
No known key found for this signature in database
GPG Key ID: 52527BEDABE87984

View File

@ -127,6 +127,58 @@ static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTrans
QApplication::installTranslator(&translator); QApplication::installTranslator(&translator);
} }
static std::string JoinErrors(const std::vector<std::string>& errors)
{
return Join(errors, "\n", [](const std::string& error) { return "- " + error; });
}
static bool InitSettings()
{
if (!gArgs.GetSettingsPath()) {
return true; // Do nothing if settings file disabled.
}
std::vector<std::string> errors;
if (!gArgs.ReadSettingsFile(&errors)) {
bilingual_str error = _("Settings file could not be read");
InitError(Untranslated(strprintf("%s:\n%s\n", error.original, JoinErrors(errors))));
QMessageBox messagebox(QMessageBox::Critical, PACKAGE_NAME, QString::fromStdString(strprintf("%s.", error.translated)), QMessageBox::Reset | QMessageBox::Abort);
/*: Explanatory text shown on startup when the settings file cannot be read.
Prompts user to make a choice between resetting or aborting. */
messagebox.setInformativeText(QObject::tr("Do you want to reset settings to default values, or to abort without making changes?"));
messagebox.setDetailedText(QString::fromStdString(JoinErrors(errors)));
messagebox.setTextFormat(Qt::PlainText);
messagebox.setDefaultButton(QMessageBox::Reset);
switch (messagebox.exec()) {
case QMessageBox::Reset:
break;
case QMessageBox::Abort:
return false;
default:
assert(false);
}
}
errors.clear();
if (!gArgs.WriteSettingsFile(&errors)) {
bilingual_str error = _("Settings file could not be written");
InitError(Untranslated(strprintf("%s:\n%s\n", error.original, JoinErrors(errors))));
QMessageBox messagebox(QMessageBox::Critical, PACKAGE_NAME, QString::fromStdString(strprintf("%s.", error.translated)), QMessageBox::Ok);
/*: Explanatory text shown on startup when the settings file could not be written.
Prompts user to check that we have the ability to write to the file.
Explains that the user has the option of running without a settings file.*/
messagebox.setInformativeText(QObject::tr("A fatal error occured. Check that settings file is writable, or try running with -nosettings."));
messagebox.setDetailedText(QString::fromStdString(JoinErrors(errors)));
messagebox.setTextFormat(Qt::PlainText);
messagebox.setDefaultButton(QMessageBox::Ok);
messagebox.exec();
return false;
}
return true;
}
/* qDebug() message handler --> debug.log */ /* qDebug() message handler --> debug.log */
void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg) void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg)
{ {
@ -590,9 +642,8 @@ int GuiMain(int argc, char* argv[])
// Parse URIs on command line -- this can affect Params() // Parse URIs on command line -- this can affect Params()
PaymentServer::ipcParseCommandLine(argc, argv); PaymentServer::ipcParseCommandLine(argc, argv);
#endif #endif
if (!gArgs.InitSettings(error)) {
InitError(Untranslated(error)); if (!InitSettings()) {
QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error initializing settings: %1").arg(QString::fromStdString(error)));
return EXIT_FAILURE; return EXIT_FAILURE;
} }