Mercurial > trustbridge
comparison ui/mainwindow.cpp @ 1227:a1e990947172
(issue38) Add long time error handling.
A Long Time Error is an error that will be shown to the
user if it happened at least seven times with an interval
of at least a day between occurances.
After one success a long time error will be reset.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Wed, 24 Sep 2014 15:12:40 +0200 |
parents | 1171a4778562 |
children | 05b938021a24 |
comparison
equal
deleted
inserted
replaced
1226:e401680b0cbd | 1227:a1e990947172 |
---|---|
194 QString availableFileName = mSettings.value("List/available").toString(); | 194 QString availableFileName = mSettings.value("List/available").toString(); |
195 QString installedFileName = mSettings.value("List/installed").toString(); | 195 QString installedFileName = mSettings.value("List/installed").toString(); |
196 if (!availableFileName.isEmpty()) { | 196 if (!availableFileName.isEmpty()) { |
197 mListToInstall.readList(availableFileName.toUtf8().constData()); | 197 mListToInstall.readList(availableFileName.toUtf8().constData()); |
198 if (!mListToInstall.isValid()) { | 198 if (!mListToInstall.isValid()) { |
199 handleLTE(lteInvalidList); | |
199 mCurState = TransferError; | 200 mCurState = TransferError; |
200 // Probably a bug when Qt fileName is encoded and cFileName | |
201 // fails because of this. This needs a unit test! | |
202 // Maybe check that the file is in our data directory | |
203 QFile::remove(availableFileName); | 201 QFile::remove(availableFileName); |
204 mSettings.remove("List/available"); | 202 mSettings.remove("List/available"); |
205 mSettings.remove("List/availableDate"); | 203 mSettings.remove("List/availableDate"); |
204 } else { | |
205 handleLTE(lteInvalidList, true); | |
206 } | 206 } |
207 } else { | 207 } else { |
208 // Make sure the available notation is also removed | 208 // Make sure the available notation is also removed |
209 mSettings.remove("List/available"); | 209 mSettings.remove("List/available"); |
210 mSettings.remove("List/availableDate"); | 210 mSettings.remove("List/availableDate"); |
252 } | 252 } |
253 bin_verify_result verifyResult = verify_binary(swFileName.toUtf8().constData(), | 253 bin_verify_result verifyResult = verify_binary(swFileName.toUtf8().constData(), |
254 swFileName.toUtf8().size()); | 254 swFileName.toUtf8().size()); |
255 qDebug() << "Binary verify result: " << verifyResult.result; | 255 qDebug() << "Binary verify result: " << verifyResult.result; |
256 if (verifyResult.result != VerifyValid) { | 256 if (verifyResult.result != VerifyValid) { |
257 handleLTE(lteInvalidSoftware); | |
257 qDebug() << "Failed to verify downloaded data."; | 258 qDebug() << "Failed to verify downloaded data."; |
258 QFile::remove(swFileName); | 259 QFile::remove(swFileName); |
259 mSettings.remove("Software/available"); | 260 mSettings.remove("Software/available"); |
260 mSettings.remove("Software/availableDate"); | 261 mSettings.remove("Software/availableDate"); |
261 return; | 262 return; |
262 } | 263 } |
264 handleLTE(lteInvalidSoftware, true); /* Reset error state */ | |
263 fclose(verifyResult.fptr); | 265 fclose(verifyResult.fptr); |
264 } | 266 } |
265 | 267 |
266 void MainWindow::handleNewList(const QString& fileName, const QDateTime& modDate) { | 268 void MainWindow::handleNewList(const QString& fileName, const QDateTime& modDate) { |
267 qDebug() << "new list available"; | 269 qDebug() << "new list available"; |
268 mSettings.setValue("List/available", fileName); | 270 mSettings.setValue("List/available", fileName); |
269 mSettings.setValue("List/availableDate", modDate); | 271 mSettings.setValue("List/availableDate", modDate); |
270 | 272 |
271 verifyListData(); | 273 verifyListData(); |
272 if (!mListToInstall.isValid()) { | 274 if (!mListToInstall.isValid()) { |
275 handleLTE(lteInvalidList); | |
273 /* Downloader provided invalid files */ | 276 /* Downloader provided invalid files */ |
274 /* TODO (issue38): Error count. Error handling. Otherwise | |
275 * we can go into an endless loop here */ | |
276 | 277 |
277 /* Retry the download again in 10 - 20 minutes */ | 278 /* Retry the download again in 10 - 20 minutes */ |
278 QTimer::singleShot(600000 + (qrand() % 60000), this, SLOT(checkUpdates())); | 279 QTimer::singleShot(600000 + (qrand() % 60000), this, SLOT(checkUpdates())); |
279 qDebug() << "Failed to verify list."; | 280 qDebug() << "Failed to verify list."; |
280 } else { | 281 } else { |
304 | 305 |
305 mSettings.sync(); | 306 mSettings.sync(); |
306 showMessage(); | 307 showMessage(); |
307 } | 308 } |
308 | 309 |
309 QString getPrettyInstallerName(QString realFileName) { | 310 QString MainWindow::getPrettyInstallerName(QString realFileName) { |
310 QTemporaryDir tDir; | 311 QTemporaryDir tDir; |
311 if (!tDir.isValid()) { | 312 if (!tDir.isValid()) { |
312 qDebug () << "Failed to create temporary directory."; | 313 qDebug () << "Failed to create temporary directory."; |
314 showErrorMessage (tr("Failed to create temporary directory.") + "\n" + | |
315 tr("Please ensure that you have the access rights to write in " | |
316 "the temporary directory and that there is at least 20MB free " | |
317 "disk space available.")); | |
313 return QString(); | 318 return QString(); |
314 } | 319 } |
315 QString targetPath = tDir.path() + "/" + QObject::tr("TrustBridge-Updater", | 320 QString targetPath = tDir.path() + "/" + QObject::tr("TrustBridge-Updater", |
316 "Used as filename for the updater. Only use ASCII please."); | 321 "Used as filename for the updater. Only use ASCII please."); |
317 | 322 |
318 tDir.setAutoRemove(false); | 323 tDir.setAutoRemove(false); |
319 #ifdef WIN32 | 324 #ifdef WIN32 |
320 targetPath += ".exe"; | 325 targetPath += ".exe"; |
321 #endif | 326 #endif |
322 if (!QFile::copy(realFileName, targetPath)) { | 327 if (!QFile::copy(realFileName, targetPath)) { |
328 showErrorMessage (tr("Failed to create a temporary copy of the installer.") + "\n" + | |
329 tr("Please ensure that you have the access rights to write in " | |
330 "the temporary directory and that there is at least 20MB free " | |
331 "disk space available.")); | |
323 qDebug() << "Failed to create temporary copy of installer."; | 332 qDebug() << "Failed to create temporary copy of installer."; |
324 } | 333 } |
325 return targetPath; | 334 return targetPath; |
326 } | 335 } |
327 | 336 |
332 /* Copy the file to a temporary name for installation */ | 341 /* Copy the file to a temporary name for installation */ |
333 filePath = getPrettyInstallerName(filePath); | 342 filePath = getPrettyInstallerName(filePath); |
334 | 343 |
335 if (filePath.isEmpty()) { | 344 if (filePath.isEmpty()) { |
336 qDebug() << "Failed to copy updater to temporary location."; | 345 qDebug() << "Failed to copy updater to temporary location."; |
337 showErrorMessage(tr("Failed to create update process.") + "\n" + | |
338 tr("This could be caused by not enough disk space or invalid permissions.")); | |
339 return; | 346 return; |
340 } | 347 } |
341 mSettings.setValue("Software/Updater", filePath); /* So it can be deleted | 348 mSettings.setValue("Software/Updater", filePath); /* So it can be deleted |
342 on next start */ | 349 on next start */ |
343 mSettings.sync(); | 350 mSettings.sync(); |
344 | 351 |
345 bin_verify_result vres = verify_binary(filePath.toUtf8().constData(), | 352 bin_verify_result vres = verify_binary(filePath.toUtf8().constData(), |
346 filePath.toUtf8().size()); | 353 filePath.toUtf8().size()); |
347 | 354 |
348 if (vres.result != VerifyValid) { | 355 if (vres.result != VerifyValid) { |
356 handleLTE(lteInvalidSoftware); | |
349 qDebug() << "Invalid software. Not installing"; | 357 qDebug() << "Invalid software. Not installing"; |
350 return; | 358 return; |
351 } | 359 } |
360 handleLTE(lteInvalidSoftware, true); | |
352 QFileInfo fi(QCoreApplication::applicationFilePath()); | 361 QFileInfo fi(QCoreApplication::applicationFilePath()); |
353 QDir installDir = fi.absoluteDir(); | 362 QDir installDir = fi.absoluteDir(); |
354 | 363 |
355 #ifdef WIN32 | 364 #ifdef WIN32 |
356 QString parameters = QString::fromLatin1("/S /UPDATE=1 /D=") + | 365 QString parameters = QString::fromLatin1("/S /UPDATE=1 /D=") + |
569 checkUpdates(); | 578 checkUpdates(); |
570 } | 579 } |
571 | 580 |
572 void MainWindow::downloaderError(const QString &message, SSLConnection::ErrorCode error) | 581 void MainWindow::downloaderError(const QString &message, SSLConnection::ErrorCode error) |
573 { | 582 { |
574 /* TODO (issue38) handle error according to a plan */ | |
575 syslog_error_printf ("Failed to check for updates: %s", message.toUtf8().constData()); | 583 syslog_error_printf ("Failed to check for updates: %s", message.toUtf8().constData()); |
584 if (error == SSLConnection::InvalidCertificate) { | |
585 handleLTE(lteInvalidCertificate); | |
586 } else { | |
587 handleLTE(lteNoConnection); | |
588 } | |
576 #ifdef IS_TAG_BUILD | 589 #ifdef IS_TAG_BUILD |
577 /* During tag build it should never happen that an url checked is not available | 590 /* During tag build it should never happen that an url checked is not available |
578 * during development this is normal as each revision produces a new url. */ | 591 * during development this is normal as each revision produces a new url. */ |
579 setState(TransferError); | 592 setState(TransferError); |
580 if (!isVisible()) { | 593 if (!isVisible()) { |
1645 mSettings.setValue("lastUpdateCheck", now); | 1658 mSettings.setValue("lastUpdateCheck", now); |
1646 mLastUpdateCheckContents->setText(QLocale::system().toString(now, DATETIME_FORMAT)); | 1659 mLastUpdateCheckContents->setText(QLocale::system().toString(now, DATETIME_FORMAT)); |
1647 mLastUpdateCheckContents->show(); | 1660 mLastUpdateCheckContents->show(); |
1648 mLastUpdateCheck->show(); | 1661 mLastUpdateCheck->show(); |
1649 syslog_info_printf(tr("Sucessfully checked for updates.").toUtf8().constData()); | 1662 syslog_info_printf(tr("Sucessfully checked for updates.").toUtf8().constData()); |
1663 handleLTE(lteNoConnection, true); /* Reset error state */ | |
1664 handleLTE(lteInvalidCertificate, true); | |
1650 } | 1665 } |
1651 if ((getState() != NewSoftwareAvailable && getState() != NewListAvailable && mTrayMode) | 1666 if ((getState() != NewSoftwareAvailable && getState() != NewListAvailable && mTrayMode) |
1652 && !isVisible()) { | 1667 && !isVisible()) { |
1653 qDebug() << "Shutting down as no list or Software is available."; | 1668 qDebug() << "Shutting down as no list or Software is available."; |
1654 closeApp(); | 1669 closeApp(); |
1702 | 1717 |
1703 void MainWindow::showErrorMessage(const QString &msg) | 1718 void MainWindow::showErrorMessage(const QString &msg) |
1704 { | 1719 { |
1705 QMessageBox::warning(this, tr("TrustBridge error"), msg); | 1720 QMessageBox::warning(this, tr("TrustBridge error"), msg); |
1706 } | 1721 } |
1722 | |
1723 void MainWindow::handleLTE(LongTimeErrors lte, bool reset) | |
1724 { | |
1725 QString settingPrefix; | |
1726 switch (lte) { | |
1727 case lteInvalidSoftware: | |
1728 settingPrefix = "LTE/invalidSW"; | |
1729 break; | |
1730 case lteInvalidList: | |
1731 settingPrefix = "LTE/invalidList"; | |
1732 break; | |
1733 case lteInvalidCertificate: | |
1734 settingPrefix = "LTE/invalidCertificate"; | |
1735 break; | |
1736 case lteNoConnection: | |
1737 settingPrefix = "LTE/noConnection"; | |
1738 break; | |
1739 default: | |
1740 qDebug() << "Unhandled error. " << lte; | |
1741 } | |
1742 | |
1743 if (reset) { | |
1744 /* delete all values and be done */ | |
1745 mSettings.remove(settingPrefix + "_lastSaved"); | |
1746 mSettings.remove(settingPrefix + "_count"); | |
1747 mSettings.remove(settingPrefix + "_lastMsgShown"); | |
1748 return; | |
1749 } | |
1750 | |
1751 QDateTime lastSaved = mSettings.value(settingPrefix + "_lastSaved").toDateTime(); | |
1752 bool cnt_valid; | |
1753 int cnt = mSettings.value(settingPrefix + "_count").toInt(&cnt_valid); | |
1754 if (!cnt_valid) { | |
1755 cnt = 0; | |
1756 } | |
1757 | |
1758 if (!lastSaved.isValid() || lastSaved.daysTo(QDateTime::currentDateTime()) >= 1) { | |
1759 /* The error count is increased at most once a day */ | |
1760 mSettings.setValue(settingPrefix + "_lastSaved", QDateTime::currentDateTime()); | |
1761 mSettings.setValue(settingPrefix + "_count", ++cnt); | |
1762 } | |
1763 | |
1764 | |
1765 if (cnt < 7) { | |
1766 /* We are done */ | |
1767 return; | |
1768 } | |
1769 /* A week has passed. Start showing the error. */ | |
1770 QDateTime lastShown = mSettings.value(settingPrefix + "_lastShown").toDateTime(); | |
1771 if (lastShown.isValid() && lastShown.daysTo(QDateTime::currentDateTime()) < 1) { | |
1772 /* Only show the error message once a day */ | |
1773 return; | |
1774 } | |
1775 | |
1776 mSettings.setValue(settingPrefix + "_lastShown", QDateTime::currentDateTime()); | |
1777 | |
1778 switch (lte) { | |
1779 case lteInvalidSoftware: | |
1780 showErrorMessage(tr("The integrity check for the available software update has " | |
1781 "failed repeatedly.") + "\n" + | |
1782 tr("Please contact your Support or the publisher of the Software.")); | |
1783 break; | |
1784 case lteInvalidList: | |
1785 showErrorMessage(tr("The integrity check of the available certificates has " | |
1786 "failed repeatedly.") + "\n" + | |
1787 tr("Please contact your Support or the publisher of the Software.")); | |
1788 break; | |
1789 case lteInvalidCertificate: | |
1790 showErrorMessage(tr("The authentication of the download server has " | |
1791 "failed repeatedly.") + "\n" + | |
1792 tr("Please contact your Support or the publisher of the Software.")); | |
1793 break; | |
1794 case lteNoConnection: | |
1795 bool useProxy = mSettings.value("UseProxy", false).toBool(); | |
1796 if (useProxy) { | |
1797 showErrorMessage(tr("The connection to the download server has " | |
1798 "failed repeatedly.") + "\n" + | |
1799 tr("Please check that the Proxy Server \"%1\" is available.").arg( | |
1800 mSettings.value("ProxyURL").toString())); | |
1801 } else { | |
1802 showErrorMessage(tr("The connection to the download server has " | |
1803 "failed repeatedly.") + "\n" + | |
1804 tr("Please check your internet connection.")); | |
1805 } | |
1806 break; | |
1807 } | |
1808 } |