1
0
Fork 0

Error reporting: report Traffic errors

Also add logging to Sentry.io
This commit is contained in:
James Turner 2021-03-13 18:47:01 +00:00
parent 251b3aeb2b
commit fbbcc75229
6 changed files with 94 additions and 50 deletions

View file

@ -638,6 +638,9 @@ bool FGAIBase::init(ModelSearchOrder searchOrder)
_modeldata->addErrorContext("ai", _name);
_modeldata->captureErrorContext("scenario-path");
// set by FGAISchedule::createAIAircraft
_modeldata->captureErrorContext("traffic-aircraft-callsign");
if (_otype == otMultiplayer) {
_modeldata->addErrorContext("multiplayer", getCallSign());
}

View file

@ -38,6 +38,7 @@
#include <Main/fg_props.hxx>
#include <Main/globals.hxx>
#include <Main/locale.hxx>
#include <Main/sentryIntegration.hxx>
#include <Scripting/NasalClipboard.hxx> // clipboard access
using std::string;
@ -70,7 +71,8 @@ enum class Aggregation {
FGData,
MultiPlayer,
Unknown, ///< error coudln't be attributed more specifcially
OutOfMemory ///< seperate category to give it a custom message
OutOfMemory, ///< seperate category to give it a custom message
Traffic
};
// these should correspond to simgear::ErrorCode enum
@ -111,7 +113,8 @@ string_list static_categoryIds = {
"error-category-fgdata",
"error-category-multiplayer",
"error-category-unknown",
"error-category-out-of-memory"};
"error-category-out-of-memory",
"error-category-traffic"};
class RecentLogCallback : public simgear::LogCallback
{
@ -234,6 +237,7 @@ public:
void collectError(simgear::LoadFailure type, simgear::ErrorCode code, const std::string& details, const sg_location& location)
{
SG_LOG(SG_GENERAL, SG_WARN, "Error:" << static_errorTypeIds.at(static_cast<int>(type)) << " from " << static_errorIds.at(static_cast<int>(code)) << "::" << details << "\n\t" << location.asString());
ErrorOcurrence occurrence{code, type, details, location, time(nullptr)};
// snapshot the top of the context stacks into our occurence data
@ -322,6 +326,8 @@ public:
});
assert(it != _aggregated.end());
_activeReportIndex = std::distance(_aggregated.begin(), it);
flightgear::sentryReportUserError(static_categoryIds.at(catId), detailsTextStream.str());
}
void writeReportToStream(const AggregateReport& report, std::ostream& os) const;
@ -355,6 +361,16 @@ auto ErrorReporter::ErrorReporterPrivate::getAggregateForOccurence(const ErrorRe
return getAggregate(Aggregation::MultiPlayer, {});
}
// traffic cases: need to handle errors in the traffic files (schedule, rwyuse)
// but also errors loading aircraft models associated with traffic
if (oc.code == simgear::ErrorCode::AITrafficSchedule) {
return getAggregate(Aggregation::Traffic, {});
}
if (oc.hasContextKey("traffic-aircraft-callsign")) {
return getAggregate(Aggregation::Traffic, {});
}
// all TerraSync coded errors go there: this is errors for the
// actual download process (eg, failed to write to disk)
if (oc.code == simgear::ErrorCode::TerraSync) {

View file

@ -485,6 +485,26 @@ void sentryThreadReportXMLErrors(bool report)
perThread_reportXMLParseErrors = report;
}
void sentryReportUserError(const std::string& aggregate, const std::string& details)
{
if (!static_sentryEnabled)
return;
sentry_value_t sentryMessage = sentry_value_new_object();
sentry_value_set_by_key(sentryMessage, "type", sentry_value_new_string("Error"));
sentry_value_t info = sentry_value_new_object();
sentry_value_set_by_key(info, "details", sentry_value_new_string(details.c_str()));
sentry_set_context("what", info);
sentry_value_set_by_key(sentryMessage, "value", sentry_value_new_string(aggregate.c_str()));
sentry_value_t event = sentry_value_new_event();
sentry_value_set_by_key(event, "message", sentryMessage);
sentry_capture_event(event);
}
} // of namespace
#else
@ -535,6 +555,10 @@ void sentryThreadReportXMLErrors(bool)
{
}
void sentryReportUserError(const std::string&, const std::string&)
{
}
} // of namespace
#endif

View file

@ -43,6 +43,7 @@ void sentryReportException(const std::string& msg, const std::string& location =
void sentryReportFatalError(const std::string& msg, const std::string& more = {});
void sentryReportUserError(const std::string& aggregate, const std::string& details);
/**
* @brief helper to allow per-thread supression of
* error reports based on XML parse/include errors.

View file

@ -38,12 +38,13 @@
#include <algorithm>
#include <simgear/compiler.h>
#include <simgear/sg_inlines.h>
#include <simgear/debug/ErrorReportingCallback.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/props/props.hxx>
#include <simgear/sg_inlines.h>
#include <simgear/structure/subsystem_mgr.hxx>
#include <simgear/xml/easyxml.hxx>
#include <simgear/timing/sg_time.hxx>
#include <simgear/xml/easyxml.hxx>
#include <AIModel/AIFlightPlan.hxx>
#include <AIModel/AIManager.hxx>
@ -380,6 +381,9 @@ bool FGAISchedule::createAIAircraft(FGScheduledFlight* flight, double speedKnots
speedKnots, flightType, acType,
airline));
if (fp->isValidPlan()) {
// set this here so it's available inside attach, which calls AIBase::init
simgear::ErrorReportContext ec{"traffic-aircraft-callsign", flight->getCallSign()};
aiAircraft->FGAIBase::setFlightPlan(std::move(fp));
globals->get_subsystem<FGAIManager>()->attach(aiAircraft);
if (aiAircraft->_getProps()) {

View file

@ -323,7 +323,7 @@ private:
if (!FGAISchedule::validModelPath(mdl)) {
missingModels.insert(mdl);
SG_LOG(SG_AI, SG_DEV_WARN, "TrafficMgr: Missing model path:" << mdl);
simgear::reportFailure(simgear::LoadFailure::NotFound, simgear::ErrorCode::AITrafficSchedule, "Missing traffic model path:" + mdl, _currentFile);
requiredAircraft = homePort = "";
return;
}
@ -387,6 +387,7 @@ private:
SG_LOG(SG_AI, SG_DEBUG, "parsing traffic in:" << p);
simgear::PathList trafficFiles = d2.children(simgear::Dir::TYPE_FILE, ".xml");
for (const auto& xml : trafficFiles) {
_currentFile = xml;
try {
readXML(xml, *this);
if (_cancelThread) {
@ -395,7 +396,6 @@ private:
} catch (sg_exception& e) {
simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::AITrafficSchedule,
"XML errors parsinng traffic:" + e.getFormattedMessage(), xml);
SG_LOG(SG_AI, SG_WARN, "XML error parsing traffic file:" << xml << "\n\t" << e.getFormattedMessage());
}
}
} // of sub-directories iteration
@ -408,6 +408,7 @@ private:
bool _isFinished;
bool _cancelThread;
simgear::PathList _trafficDirPaths;
SGPath _currentFile;
// parser state
@ -828,14 +829,9 @@ void FGTrafficManager::readTimeTableFromFile(SGPath infileName)
offset = atof(tokens[7].c_str());;
if (!FGAISchedule::validModelPath(model)) {
SG_LOG(SG_AI, SG_WARN, "TrafficMgr: Missing model path:" <<
model << " from " << infileName);
simgear::reportFailure(simgear::LoadFailure::NotFound, simgear::ErrorCode::AITrafficSchedule, "Missing traffic model path:" + model, infileName);
} else {
SG_LOG(SG_AI, SG_INFO, "Adding Aircraft" << model << " " << livery << " " << homePort << " "
<< registration << " " << flightReq << " " << isHeavy
<< " " << acType << " " << airline << " " << m_class
<< " " << FlightType << " " << radius << " " << offset);
SG_LOG(SG_AI, SG_DEBUG, "Adding Aircraft" << model << " " << livery << " " << homePort << " " << registration << " " << flightReq << " " << isHeavy << " " << acType << " " << airline << " " << m_class << " " << FlightType << " " << radius << " " << offset);
scheduledAircraft.push_back(new FGAISchedule(model,
livery,
homePort,