mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-05-01 22:55:41 +08:00
refs #853, JSON exception handling in setup reader
This commit is contained in:
committed by
Mathew Sutcliffe
parent
3939b0166f
commit
4a28807768
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "blackcore/application.h"
|
#include "blackcore/application.h"
|
||||||
#include "blackcore/setupreader.h"
|
#include "blackcore/setupreader.h"
|
||||||
|
#include "blackmisc/verify.h"
|
||||||
#include "blackmisc/compare.h"
|
#include "blackmisc/compare.h"
|
||||||
#include "blackmisc/fileutils.h"
|
#include "blackmisc/fileutils.h"
|
||||||
#include "blackmisc/json.h"
|
#include "blackmisc/json.h"
|
||||||
@@ -63,11 +64,10 @@ namespace BlackCore
|
|||||||
CStatusMessageList CSetupReader::asyncLoad()
|
CStatusMessageList CSetupReader::asyncLoad()
|
||||||
{
|
{
|
||||||
CStatusMessageList msgs;
|
CStatusMessageList msgs;
|
||||||
if (this->readLocalBootstrapFile(this->m_localSetupFileValue))
|
if (!this->m_localSetupFileValue.isEmpty())
|
||||||
{
|
{
|
||||||
// initialized by local file for testing
|
msgs = this->readLocalBootstrapFile(this->m_localSetupFileValue);
|
||||||
msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityInfo, "Using local bootstrap file: " + this->m_localSetupFileValue));
|
msgs.push_back(this->manageSetupAvailability(false, msgs.isSuccess()));
|
||||||
msgs.push_back(this->manageSetupAvailability(false, true));
|
|
||||||
return msgs;
|
return msgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,18 +258,18 @@ namespace BlackCore
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSetupReader::readLocalBootstrapFile(QString &fileName)
|
CStatusMessageList CSetupReader::readLocalBootstrapFile(QString &fileName)
|
||||||
{
|
{
|
||||||
if (fileName.isEmpty()) { return false; }
|
if (fileName.isEmpty()) { return CStatusMessage(this).error("No file name for local bootstrap file"); }
|
||||||
QString fn;
|
QString fn;
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
if (!file.exists())
|
if (!file.exists())
|
||||||
{
|
{
|
||||||
// relative name?
|
// relative name?
|
||||||
QString dir(sApp->getCmdSwiftPrivateSharedDir());
|
QString dir(sApp->getCmdSwiftPrivateSharedDir());
|
||||||
if (dir.isEmpty()) { return false; }
|
if (dir.isEmpty()) { return CStatusMessage(this).error("Empty shared directory '%1' for bootstrap file") << dir; }
|
||||||
|
|
||||||
// no version for local files, as those come withe the current code
|
// no version for local files, as those come with the current code
|
||||||
fn = CFileUtils::appendFilePaths(dir, "bootstrap/bootstrap.json");
|
fn = CFileUtils::appendFilePaths(dir, "bootstrap/bootstrap.json");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -278,12 +278,20 @@ namespace BlackCore
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString content(CFileUtils::readFileToString(fn));
|
QString content(CFileUtils::readFileToString(fn));
|
||||||
if (content.isEmpty()) { return false; }
|
if (content.isEmpty()) { return CStatusMessage(this).error("File '%1' not existing or empty") << fn; }
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
CGlobalSetup s;
|
CGlobalSetup s;
|
||||||
s.convertFromJson(content); //! \todo catch CJsonException or use convertFromJsonNoThrow
|
s.convertFromJson(content);
|
||||||
s.setDevelopment(true);
|
s.setDevelopment(true);
|
||||||
m_setup.set(s);
|
m_setup.set(s);
|
||||||
return true;
|
return CStatusMessage(this).info("Setup cache updated from local file '%1'") << fn;
|
||||||
|
}
|
||||||
|
catch (const CJsonException &ex)
|
||||||
|
{
|
||||||
|
return ex.toStatusMessage(this, QString("Parsing local setup file '%1'").arg(fn));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSetupReader::ps_parseSetupFile(QNetworkReply *nwReplyPtr)
|
void CSetupReader::ps_parseSetupFile(QNetworkReply *nwReplyPtr)
|
||||||
@@ -304,14 +312,16 @@ namespace BlackCore
|
|||||||
nwReplyPtr->close();
|
nwReplyPtr->close();
|
||||||
if (setupJson.isEmpty())
|
if (setupJson.isEmpty())
|
||||||
{
|
{
|
||||||
CLogMessage(this).info("No bootstrap setup file at %1") << urlString;
|
CLogMessage(this).info("No bootstrap setup file at '%1'") << urlString;
|
||||||
// try next URL
|
// try next URL
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
const CGlobalSetup currentSetup = m_setup.get();
|
const CGlobalSetup currentSetup = m_setup.get();
|
||||||
CGlobalSetup loadedSetup;
|
CGlobalSetup loadedSetup;
|
||||||
loadedSetup.convertFromJson(Json::jsonObjectFromString(setupJson)); //! \todo catch CJsonException or use convertFromJsonNoThrow
|
loadedSetup.convertFromJson(Json::jsonObjectFromString(setupJson));
|
||||||
loadedSetup.markAsLoaded(true);
|
loadedSetup.markAsLoaded(true);
|
||||||
if (lastModified > 0 && lastModified > loadedSetup.getMSecsSinceEpoch()) { loadedSetup.setMSecsSinceEpoch(lastModified); }
|
if (lastModified > 0 && lastModified > loadedSetup.getMSecsSinceEpoch()) { loadedSetup.setMSecsSinceEpoch(lastModified); }
|
||||||
bool sameVersionLoaded = (loadedSetup == currentSetup);
|
bool sameVersionLoaded = (loadedSetup == currentSetup);
|
||||||
@@ -331,10 +341,23 @@ namespace BlackCore
|
|||||||
{
|
{
|
||||||
// no issue with cache
|
// no issue with cache
|
||||||
this->m_updateInfoUrls = loadedSetup.getUpdateInfoFileUrls();
|
this->m_updateInfoUrls = loadedSetup.getUpdateInfoFileUrls();
|
||||||
CLogMessage(this).info("Setup: Updated data cache in %1") << this->m_setup.getFilename();
|
CLogMessage(this).info("Setup: Updated data cache in '%1'") << this->m_setup.getFilename();
|
||||||
}
|
}
|
||||||
CLogMessage::preformatted(this->manageSetupAvailability(true));
|
CLogMessage::preformatted(this->manageSetupAvailability(true));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
catch (const CJsonException &ex)
|
||||||
|
{
|
||||||
|
// we downloaded an unparsable JSON file.
|
||||||
|
// as we control those files something is wrong
|
||||||
|
const QString errorMsg = QString("Setup file loaded from '%1' cannot be parsed").arg(urlString);
|
||||||
|
const CStatusMessage msg = ex.toStatusMessage(this, errorMsg);
|
||||||
|
CLogMessage::preformatted(msg);
|
||||||
|
|
||||||
|
// in dev. I get notified, in productive code I try next URL
|
||||||
|
// by falling thru
|
||||||
|
BLACK_VERIFY_X(false, Q_FUNC_INFO, errorMsg.toLocal8Bit().constData());
|
||||||
|
}
|
||||||
} // json empty
|
} // json empty
|
||||||
} // no error
|
} // no error
|
||||||
else
|
else
|
||||||
@@ -381,10 +404,12 @@ namespace BlackCore
|
|||||||
// try next URL
|
// try next URL
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
CUpdateInfo currentUpdateInfo(m_updateInfo.get()); // from cache
|
CUpdateInfo currentUpdateInfo(m_updateInfo.get()); // from cache
|
||||||
CUpdateInfo loadedUpdateInfo;
|
CUpdateInfo loadedUpdateInfo;
|
||||||
loadedUpdateInfo.convertFromJson(Json::jsonObjectFromString(setupJson)); //! \todo catch CJsonException or use convertFromJsonNoThrow
|
loadedUpdateInfo.convertFromJson(Json::jsonObjectFromString(setupJson));
|
||||||
if (lastModified > 0 && lastModified > loadedUpdateInfo.getMSecsSinceEpoch()) { loadedUpdateInfo.setMSecsSinceEpoch(lastModified); }
|
if (lastModified > 0 && lastModified > loadedUpdateInfo.getMSecsSinceEpoch()) { loadedUpdateInfo.setMSecsSinceEpoch(lastModified); }
|
||||||
const bool sameVersionLoaded = (loadedUpdateInfo == currentUpdateInfo);
|
const bool sameVersionLoaded = (loadedUpdateInfo == currentUpdateInfo);
|
||||||
if (sameVersionLoaded)
|
if (sameVersionLoaded)
|
||||||
@@ -408,6 +433,19 @@ namespace BlackCore
|
|||||||
this->manageUpdateAvailability(true);
|
this->manageUpdateAvailability(true);
|
||||||
return; // success
|
return; // success
|
||||||
} // cache
|
} // cache
|
||||||
|
}
|
||||||
|
catch (const CJsonException &ex)
|
||||||
|
{
|
||||||
|
// we downloaded an unparsable JSON file.
|
||||||
|
// as we control those files something is wrong
|
||||||
|
const QString errorMsg = QString("Update file loaded from '%1' cannot be parsed").arg(urlString);
|
||||||
|
const CStatusMessage msg = ex.toStatusMessage(this, errorMsg);
|
||||||
|
CLogMessage::preformatted(msg);
|
||||||
|
|
||||||
|
// in dev. I get notified, in productive code I try next URL
|
||||||
|
// by falling thru
|
||||||
|
BLACK_VERIFY_X(false, Q_FUNC_INFO, errorMsg.toLocal8Bit().constData());
|
||||||
|
}
|
||||||
} // json empty
|
} // json empty
|
||||||
} // no error
|
} // no error
|
||||||
else
|
else
|
||||||
@@ -427,7 +465,7 @@ namespace BlackCore
|
|||||||
const CStatusMessageList msgs = this->manageSetupAvailability(false);
|
const CStatusMessageList msgs = this->manageSetupAvailability(false);
|
||||||
CLogMessage::preformatted(msgs);
|
CLogMessage::preformatted(msgs);
|
||||||
}
|
}
|
||||||
} // function
|
}
|
||||||
|
|
||||||
const CLogCategoryList &CSetupReader::getLogCategories()
|
const CLogCategoryList &CSetupReader::getLogCategories()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -143,12 +143,12 @@ namespace BlackCore
|
|||||||
BlackMisc::CData<BlackCore::Data::TUpdateInfo> m_updateInfo {this}; //!< data cache update info
|
BlackMisc::CData<BlackCore::Data::TUpdateInfo> m_updateInfo {this}; //!< data cache update info
|
||||||
|
|
||||||
//! Read by local individual file and update cache from that
|
//! Read by local individual file and update cache from that
|
||||||
bool readLocalBootstrapFile(QString &fileName);
|
BlackMisc::CStatusMessageList readLocalBootstrapFile(QString &fileName);
|
||||||
|
|
||||||
//! Trigger reading
|
//! Trigger reading
|
||||||
BlackMisc::CStatusMessageList triggerReadSetup();
|
BlackMisc::CStatusMessageList triggerReadSetup();
|
||||||
|
|
||||||
//! Emit the availability signal and state
|
//! Emit the availability signal and state and trigger follow up actions
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
BlackMisc::CStatusMessageList manageSetupAvailability(bool webRead, bool localRead = false);
|
BlackMisc::CStatusMessageList manageSetupAvailability(bool webRead, bool localRead = false);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user