Skip to content

Commit

Permalink
Converted the exception to an error message (#5531)
Browse files Browse the repository at this point in the history
* Converted the exception to an error message

refs: #5530

* Converted a JSON settings file exception to an error.

refs: #5530

* Fix infinite loop when bad option is encountered

* Copyright :shakes-fist:

* Capture the log output to a string if desired, compare that in the Settings unit tests.

* Copyright

Co-authored-by: Ben Marchant <[email protected]>
  • Loading branch information
mattjdnv and bmarchant authored Jan 13, 2023
1 parent aa65e4a commit b150146
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 25 deletions.
15 changes: 7 additions & 8 deletions hoot-core-test/src/test/cpp/hoot/core/util/SettingsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* This will properly maintain the copyright information. Maxar
* copyrights will be updated automatically.
*
* @copyright Copyright (C) 2012, 2013, 2015, 2016, 2018, 2019, 2020, 2021, 2022 Maxar (http://www.maxar.com/)
* @copyright Copyright (C) 2012, 2013, 2015, 2016, 2018, 2019, 2020, 2021, 2022, 2023 Maxar (http://www.maxar.com/)
*/

// Hoot
Expand Down Expand Up @@ -146,19 +146,18 @@ class SettingsTest : public HootTestFixture

void invalidOptionNameTest()
{
QString log;
QStringList args;
args.append("-D");
args.append("blah=true");
QString exceptionMsg;
try
// Capture the log output in a nested scope
{
CaptureLog capture;
Settings::parseCommonArguments(args);
log = capture.getLogsStripped();
}
catch (const HootException& e)
{
exceptionMsg = e.what();
}
HOOT_STR_EQUALS("Unknown settings option: (blah)", exceptionMsg);
// Compare the captured log output
HOOT_STR_EQUALS("Skipping unknown settings option: (blah)", log);
}

void invalidOperatorsTest()
Expand Down
40 changes: 27 additions & 13 deletions hoot-core/src/main/cpp/hoot/core/util/Log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* This will properly maintain the copyright information. Maxar
* copyrights will be updated automatically.
*
* @copyright Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Maxar (http://www.maxar.com/)
* @copyright Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Maxar (http://www.maxar.com/)
*/

#include "Log.h"
Expand Down Expand Up @@ -116,12 +116,13 @@ void Log::log(WarningLevel level, const string& str, const string& filename,
QDateTime dt = QDateTime::currentDateTime();

// takes the form: "09:34:21.635 WARN <filename>(<lineNumber>) <str>"
cout << beginDecoration(level)
<< dt.toString("hh:mm:ss.zzz") << " " << setw(6) << left << Log::levelToString(level)
<< " " << ellipsisStr(filename) << "(" << setw(4) << right << lineNumber << ")" << " "
<< str
<< endDecoration()
<< endl;
std::ostream& s = *_stream;
s << beginDecoration(level)
<< dt.toString("hh:mm:ss.zzz") << " " << setw(6) << left << Log::levelToString(level)
<< " " << ellipsisStr(filename) << "(" << setw(4) << right << lineNumber << ")" << " "
<< str
<< endDecoration()
<< endl;
}
}

Expand All @@ -133,12 +134,13 @@ void Log::progress(WarningLevel level, const string& str, const string& filename
QDateTime dt = QDateTime::currentDateTime();

// takes the form: "09:34:21.635 WARN <filename>(<lineNumber>) <str>"
cout << beginDecoration(level)
<< dt.toString("hh:mm:ss.zzz") << " " << setw(6) << left << Log::levelToString(level)
<< " " << ellipsisStr(filename) << "(" << setw(4) << right << lineNumber << ")" << " "
<< str << " \r"
<< endDecoration()
<< flush;
std::ostream& s = *_stream;
s << beginDecoration(level)
<< dt.toString("hh:mm:ss.zzz") << " " << setw(6) << left << Log::levelToString(level)
<< " " << ellipsisStr(filename) << "(" << setw(4) << right << lineNumber << ")" << " "
<< str << " \r"
<< endDecoration()
<< flush;
}
}

Expand Down Expand Up @@ -295,4 +297,16 @@ const char* Log::endDecoration() const
return "";
}

QString CaptureLog::getLogsStripped() const
{
static QRegularExpression regex(".*?\\( *\\d+\\) (.*)", QRegularExpression::OptimizeOnFirstUsageOption);

QString logs = getLogs();
QStringList matches;
auto match_it = regex.globalMatch(logs);
while (match_it.hasNext())
matches << match_it.next().captured(1);
return matches.join("\n");
}

}
38 changes: 37 additions & 1 deletion hoot-core/src/main/cpp/hoot/core/util/Log.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* This will properly maintain the copyright information. Maxar
* copyrights will be updated automatically.
*
* @copyright Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Maxar (http://www.maxar.com/)
* @copyright Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Maxar (http://www.maxar.com/)
*/

#ifndef LOG_H
Expand All @@ -36,6 +36,7 @@

// Standard
#include <deque>
#include <iostream>
#include <set>
#include <string>
#include <vector>
Expand Down Expand Up @@ -128,6 +129,9 @@ class Log

void setDecorateLogs(bool decorate) { _decorateLogs = decorate; }

std::ostream* getStream() const { return _stream; }
void setStream(std::ostream* stream) { _stream = stream; }

private:

WarningLevel _level;
Expand All @@ -136,6 +140,9 @@ class Log
QStringList _excludeClassFilter;
bool _decorateLogs;

/** By default all logging goes to std::cout */
std::ostream* _stream = &std::cout;

Log();
/** Default destructor */
~Log() = default;
Expand Down Expand Up @@ -189,6 +196,35 @@ class DisableLog
Log::WarningLevel _oldLevel;
};

class CaptureLog
{
public:
CaptureLog(Log::WarningLevel level = Log::Error)
{
Log& log = Log::getInstance();
_stream = log.getStream();
_level = log.getLevel();
log.setLevel(level);
log.setStream(&_strstream);
}

~CaptureLog()
{
Log& log = Log::getInstance();
log.setLevel(_level);
log.setStream(_stream);
}

QString getLogs() const { return QString(_strstream.str().c_str()); }
QString getLogsStripped() const;

private:

Log::WarningLevel _level;
std::ostream* _stream;
std::stringstream _strstream;
};

// recreate the TGS stream utils within our namespace. I haven't found an elegant way to reliably
// use operator<< within the Tgs namespace from within hoot. :(
#include <tgs/StreamUtils.hh>
Expand Down
14 changes: 11 additions & 3 deletions hoot-core/src/main/cpp/hoot/core/util/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* This will properly maintain the copyright information. Maxar
* copyrights will be updated automatically.
*
* @copyright Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Maxar (http://www.maxar.com/)
* @copyright Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Maxar (http://www.maxar.com/)
*/

#include "Settings.h"
Expand Down Expand Up @@ -142,7 +142,10 @@ class JsonLoader

// Throw an exception for unrecognized keys
if (!_s->hasKey(optionName))
throw IllegalArgumentException("Unknown JSON setting: (" + optionName + ")");
{
LOG_ERROR("Skipping unknown JSON setting: (" << optionName << ")");
continue;
}

// Set key/value pair as name and data, data() turns everything to a string
const QString optionVal = QString::fromUtf8(element.second.data().c_str());
Expand Down Expand Up @@ -636,7 +639,12 @@ void Settings::parseCommonArguments(QStringList& args, const QStringList toIgnor
LOG_VART(optionVal);

if (!conf().hasKey(optionName))
throw IllegalArgumentException("Unknown settings option: (" + optionName + ")");
{
LOG_ERROR("Skipping unknown settings option: (" << optionName << ")");
// move on to the next argument
args = args.mid(2);
continue;
}

const QStringList values = optionVal.split(";", QString::SkipEmptyParts);
LOG_VART(values);
Expand Down

0 comments on commit b150146

Please sign in to comment.