Emit time stamp parsing errors like other parsing errors

This commit is contained in:
Martchus 2021-05-21 22:34:42 +02:00
parent 62e7797558
commit 7ad82c9dfe
3 changed files with 34 additions and 66 deletions

View File

@ -688,6 +688,22 @@ SyncthingDev *SyncthingConnection::addDevInfo(std::vector<SyncthingDev> &devs, c
return &devs.back();
}
/*!
* \brief Internally called to parse a time stamp.
*/
DateTime SyncthingConnection::parseTimeStamp(const QJsonValue &jsonValue, const QString &context, DateTime defaultValue, bool greaterThanEpoch)
{
const auto utf16 = jsonValue.toString();
const auto utf8 = utf16.toUtf8();
try {
const auto [localTime, utcOffset] = DateTime::fromIsoString(utf8.data());
return !greaterThanEpoch || (localTime - utcOffset) > DateTime::unixEpochStart() ? localTime : defaultValue;
} catch (const ConversionException &e) {
emit error(tr("Unable to parse timestamp \"%1\" (%2): %3").arg(utf16, context, QString::fromUtf8(e.what())), SyncthingErrorCategory::Parsing, QNetworkReply::NoError);
}
return defaultValue;
}
/*!
* \brief Continues connecting if both - config and status - have been parsed yet and continuous polling is enabled.
*/

View File

@ -345,6 +345,7 @@ private:
bool pauseResumeDirectory(const QStringList &dirIds, bool paused);
SyncthingDir *addDirInfo(std::vector<SyncthingDir> &dirs, const QString &dirId);
SyncthingDev *addDevInfo(std::vector<SyncthingDev> &devs, const QString &devId);
CppUtilities::DateTime parseTimeStamp(const QJsonValue &jsonValue, const QString &context, CppUtilities::DateTime defaultValue = CppUtilities::DateTime(), bool greaterThanEpoch = false);
QString m_syncthingUrl;
QByteArray m_apiKey;

View File

@ -672,15 +672,8 @@ void SyncthingConnection::readStatus()
}
const auto replyObj = replyDoc.object();
const auto startTime = replyObj.value(QLatin1String("startTime")).toString().toUtf8();
emitMyIdChanged(replyObj.value(QLatin1String("myID")).toString());
try {
m_startTime = DateTime::fromIsoStringLocal(startTime.data());
} catch (const ConversionException &e) {
m_startTime = DateTime(); // tracking the start time isn't very important so just ignore
cerr << EscapeCodes::Phrases::Warning << "Unable to parse start time timestamp \"" << startTime.data() << "\": " << e.what()
<< EscapeCodes::Phrases::End;
}
m_startTime = parseTimeStamp(replyObj.value(QLatin1String("startTime")), QStringLiteral("start time"));
m_hasStatus = true;
if (m_keepPolling) {
@ -861,15 +854,8 @@ void SyncthingConnection::readErrors()
if (errorObj.isEmpty()) {
continue;
}
const auto whenStr = errorObj.value(QLatin1String("when")).toString().toUtf8();
try {
const auto when = DateTime::fromIsoStringLocal(whenStr.data());
if (m_lastErrorTime < when) {
emitNotification(m_lastErrorTime = when, errorObj.value(QLatin1String("message")).toString());
}
} catch (const ConversionException &e) {
cerr << EscapeCodes::Phrases::Warning << "Unable to parse error message timestamp \"" << whenStr.data() << "\": " << e.what()
<< EscapeCodes::Phrases::End;
if (const auto when = parseTimeStamp(errorObj.value(QLatin1String("when")), QStringLiteral("error message")); m_lastErrorTime < when) {
emitNotification(m_lastErrorTime = when, errorObj.value(QLatin1String("message")).toString());
}
}
@ -934,13 +920,7 @@ void SyncthingConnection::readDirStatistics()
const auto lastScan = dirObj.value(QLatin1String("lastScan")).toString().toUtf8();
if (!lastScan.isEmpty()) {
dirModified = true;
try {
dirInfo.lastScanTime = DateTime::fromIsoStringLocal(lastScan.data());
} catch (const ConversionException &e) {
dirInfo.lastScanTime = DateTime();
cerr << EscapeCodes::Phrases::Warning << "Unable to parse last scan timestamp \"" << lastScan.data() << "\": " << e.what()
<< EscapeCodes::Phrases::End;
}
dirInfo.lastScanTime = parseTimeStamp(dirObj.value(QLatin1String("lastScan")), QStringLiteral("last scan"));
}
const QJsonObject lastFileObj(dirObj.value(QLatin1String("lastFile")).toObject());
if (!lastFileObj.isEmpty()) {
@ -948,15 +928,11 @@ void SyncthingConnection::readDirStatistics()
dirModified = true;
if (!dirInfo.lastFileName.isEmpty()) {
dirInfo.lastFileDeleted = lastFileObj.value(QLatin1String("deleted")).toBool(false);
try {
dirInfo.lastFileTime = DateTime::fromIsoStringLocal(lastFileObj.value(QLatin1String("at")).toString().toUtf8().data());
if (dirInfo.lastFileTime > m_lastFileTime) {
m_lastFileTime = dirInfo.lastFileTime;
m_lastFileName = dirInfo.lastFileName;
m_lastFileDeleted = dirInfo.lastFileDeleted;
}
} catch (const ConversionException &) {
dirInfo.lastFileTime = DateTime();
dirInfo.lastFileTime = parseTimeStamp(lastFileObj.value(QLatin1String("at")), QStringLiteral("dir statistics"));
if (!dirInfo.lastFileTime.isNull() && dirInfo.lastFileTime > m_lastFileTime) {
m_lastFileTime = dirInfo.lastFileTime;
m_lastFileName = dirInfo.lastFileName;
m_lastFileDeleted = dirInfo.lastFileDeleted;
}
}
}
@ -1211,16 +1187,8 @@ void SyncthingConnection::readDeviceStatistics()
for (SyncthingDev &devInfo : m_devs) {
const QJsonObject devObj(replyObj.value(devInfo.id).toObject());
if (!devObj.isEmpty()) {
const auto lastSeen = devObj.value(QLatin1String("lastSeen")).toString().toUtf8();
try {
const auto [localTime, utcOffset] = DateTime::fromIsoString(lastSeen.data());
devInfo.lastSeen = (localTime - utcOffset) > DateTime::unixEpochStart() ? localTime : DateTime();
emit devStatusChanged(devInfo, index);
} catch (const ConversionException &e) {
devInfo.lastSeen = DateTime();
cerr << EscapeCodes::Phrases::Warning << "Unable to parse last seen timestamp \"" << lastSeen.data() << "\": " << e.what()
<< EscapeCodes::Phrases::End;
}
devInfo.lastSeen = parseTimeStamp(devObj.value(QLatin1String("lastSeen")), QStringLiteral("last seen"), DateTime(), true);
emit devStatusChanged(devInfo, index);
}
++index;
}
@ -1450,16 +1418,8 @@ void SyncthingConnection::readDirSummary(DateTime eventTime, const QJsonObject &
dir.lastStatisticsUpdate = eventTime;
// update status
const auto state = summary.value(QLatin1String("state")).toString();
if (!state.isEmpty()) {
const auto stateChanged = summary.value(QLatin1String("stateChanged")).toString().toUtf8();
try {
dir.assignStatus(state, DateTime::fromIsoStringLocal(stateChanged.data()));
} catch (const ConversionException &e) {
dir.assignStatus(state, dir.lastStatusUpdate);
cerr << EscapeCodes::Phrases::Warning << "Unable to parse folder state timestamp \"" << stateChanged.data() << "\": " << e.what()
<< EscapeCodes::Phrases::End;
}
if (const auto state = summary.value(QLatin1String("state")).toString(); !state.isEmpty()) {
dir.assignStatus(state, parseTimeStamp(summary.value(QLatin1String("stateChanged")), QStringLiteral("state changed"), dir.lastStatusUpdate));
}
dir.completionPercentage = globalStats.bytes ? static_cast<int>((globalStats.bytes - neededStats.bytes) * 100 / globalStats.bytes) : 100;
@ -1612,19 +1572,10 @@ void SyncthingConnection::readEvents()
void SyncthingConnection::readEventsFromJsonArray(const QJsonArray &events, int &idVariable)
{
for (const auto &eventVal : events) {
const auto event(eventVal.toObject());
const auto eventTime([&] {
const auto timestamp = event.value(QLatin1String("time")).toString().toUtf8();
try {
return DateTime::fromIsoStringLocal(timestamp);
} catch (const ConversionException &e) {
cerr << EscapeCodes::Phrases::Warning << "Unable to parse event timestamp \"" << timestamp.data() << "\": " << e.what()
<< EscapeCodes::Phrases::End;
return DateTime(); // ignore conversion error
}
}());
const auto eventType(event.value(QLatin1String("type")).toString());
const auto eventData(event.value(QLatin1String("data")).toObject());
const auto event = eventVal.toObject();
const auto eventTime = parseTimeStamp(event.value(QLatin1String("time")), QStringLiteral("event time"));
const auto eventType = event.value(QLatin1String("type")).toString();
const auto eventData = event.value(QLatin1String("data")).toObject();
idVariable = event.value(QLatin1String("id")).toInt(idVariable);