From b8b88995cfb020a75621aa206bd84d267112071a Mon Sep 17 00:00:00 2001 From: James Turner Date: Fri, 19 Feb 2021 17:40:39 +0000 Subject: [PATCH] Add failure reporting / context to various places. Not total coverage by far, but working through the list of common failure points as seen on Sentry --- simgear/io/sg_binobj.cxx | 5 +++- simgear/scene/material/Effect.cxx | 15 +++++++----- simgear/scene/material/TextureBuilder.cxx | 28 +++++++++++++++++++--- simgear/scene/model/SGReaderWriterXML.cxx | 29 ++++++++++++++++------- simgear/scene/model/animation.cxx | 11 +++++++++ simgear/scene/tgdb/ReaderWriterSTG.cxx | 8 +++++-- simgear/scene/tgdb/SGReaderWriterBTG.cxx | 7 ++++-- 7 files changed, 81 insertions(+), 22 deletions(-) diff --git a/simgear/io/sg_binobj.cxx b/simgear/io/sg_binobj.cxx index f8ede335..c1adc220 100644 --- a/simgear/io/sg_binobj.cxx +++ b/simgear/io/sg_binobj.cxx @@ -41,9 +41,10 @@ #include #include +#include +#include #include #include -#include #include #include "lowlevel.hxx" @@ -510,6 +511,8 @@ bool SGBinObject::read_bin( const SGPath& file ) { unsigned int nbytes; sgSimpleBuffer buf( 32768 ); // 32 Kb + simgear::ErrorReportContext ec("btg", file.utf8Str()); + // zero out structures gbs_center = SGVec3d(0, 0, 0); gbs_radius = 0.0; diff --git a/simgear/scene/material/Effect.cxx b/simgear/scene/material/Effect.cxx index b85cdcfe..b3ad2961 100644 --- a/simgear/scene/material/Effect.cxx +++ b/simgear/scene/material/Effect.cxx @@ -67,17 +67,17 @@ #include #include -#include +#include +#include +#include +#include #include #include +#include #include #include #include #include -#include -#include - -#include namespace simgear { @@ -936,7 +936,8 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass, if (fileName.empty()) { SG_LOG(SG_INPUT, SG_ALERT, "Could not locate shader" << shaderName); - + simgear::reportFailure(simgear::LoadFailure::NotFound, simgear::ErrorCode::MissingShader, + "Couldn't locate shader:" + shaderName, sg_location{shaderName}); throw BuilderException(string("couldn't find shader ") + shaderName); @@ -1484,6 +1485,8 @@ bool Effect::realizeTechniques(const SGReaderWriterOptions* options) if (_isRealized) return true; + simgear::ErrorReportContext ec{"effect", getName()}; + mergeSchemesFallbacks(this, options); PropertyList tniqList = root->getChildren("technique"); diff --git a/simgear/scene/material/TextureBuilder.cxx b/simgear/scene/material/TextureBuilder.cxx index f4ed63c9..66dc8159 100644 --- a/simgear/scene/material/TextureBuilder.cxx +++ b/simgear/scene/material/TextureBuilder.cxx @@ -40,12 +40,13 @@ #include #include +#include +#include #include #include #include #include #include -#include namespace simgear { @@ -274,7 +275,16 @@ bool setAttrs(const TexTuple& attrs, Texture* tex, options->setLoadOriginHint(SGReaderWriterOptions::LoadOriginHint::ORIGIN_EFFECTS_NORMALIZED); else options->setLoadOriginHint(SGReaderWriterOptions::LoadOriginHint::ORIGIN_EFFECTS); - result = osgDB::readRefImageFile(imageName, options); + + try { + result = osgDB::readRefImageFile(imageName, options); + } catch (std::exception& e) { + simgear::reportFailure(simgear::LoadFailure::OutOfMemory, simgear::ErrorCode::LoadingTexture, + string{"osgDB::readRefImageFile failed:"} + e.what(), + SGPath::fromUtf8(imageName)); + return false; + } + options->setLoadOriginHint(origLOH); osg::ref_ptr image; if (result.success()) @@ -293,6 +303,9 @@ bool setAttrs(const TexTuple& attrs, Texture* tex, tex->setMaxAnisotropy(SGSceneFeatures::instance()->getTextureFilter()); } else { SG_LOG(SG_INPUT, SG_ALERT, "failed to load effect texture file " << imageName); + simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::LoadingTexture, + "osgDB::readRefImageFile failed:" + result.message(), + SGPath::fromUtf8(imageName)); return false; } @@ -577,8 +590,8 @@ Texture* CubeMapBuilder::build(Effect* effect, const SGPropertyNode* props, const SGPropertyNode* texturesProp = getEffectPropertyChild(effect, props, "images"); const SGPropertyNode* crossProp = getEffectPropertyChild(effect, props, "image"); if (!texturesProp && !crossProp) { + simgear::reportFailure(simgear::LoadFailure::NotFound, simgear::ErrorCode::LoadingTexture, "No images defined for cube map"); throw BuilderException("no images defined for cube map"); - return NULL; // This is redundant } // Using 6 separate images @@ -734,6 +747,9 @@ Texture* CubeMapBuilder::build(Effect* effect, const SGPropertyNode* props, return cubeTexture.release(); } else { + simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::LoadingTexture, + "Could not load cube-map image:" + result.message(), + sg_location{texname}); throw BuilderException("Could not load cube cross"); } } @@ -800,6 +816,9 @@ Texture* Texture2DArrayBuilder::build(Effect* effect, } else { SG_LOG(SG_INPUT, SG_ALERT, "failed to load effect texture file '" << pair.second << "'"); + simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::LoadingTexture, + "osgDB::readRefImageFile failed:" + result.message(), + SGPath::fromUtf8(pair.second)); return nullptr; } } @@ -884,6 +903,9 @@ Texture* Texture3DBuilder::build(Effect* effect, tex->setImage(image3d.get()); } else { SG_LOG(SG_INPUT, SG_ALERT, "failed to load effect texture file " << imageName); + simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::LoadingTexture, + "osgDB::readRefImageFile failed:" + result.message(), + SGPath::fromUtf8(imageName)); return NULL; } diff --git a/simgear/scene/model/SGReaderWriterXML.cxx b/simgear/scene/model/SGReaderWriterXML.cxx index 71bdab0f..8d897bbb 100644 --- a/simgear/scene/model/SGReaderWriterXML.cxx +++ b/simgear/scene/model/SGReaderWriterXML.cxx @@ -35,12 +35,13 @@ #include #include -#include +#include +#include #include #include -#include #include #include +#include #include "modellib.hxx" #include "SGReaderWriterXML.hxx" @@ -81,6 +82,7 @@ SGReaderWriterXML::readNode(const std::string& name, const osgDB::Options* options) const { std::string fileName = osgDB::findDataFile(name, options); + simgear::ErrorReportContext ec{"model-xml", fileName}; osg::Node *result=0; try { @@ -500,8 +502,10 @@ sgLoad3DModel_internal(const SGPath& path, SGPropertyNode *overlay) { if (!path.exists()) { - SG_LOG(SG_IO, SG_DEV_ALERT, "Failed to load file: \"" << path << "\""); - return std::make_tuple(0, (osg::Node *) NULL); + simgear::reportFailure(simgear::LoadFailure::NotFound, simgear::ErrorCode::XMLModelLoad, + "Failed to load model XML: not found", path); + SG_LOG(SG_IO, SG_DEV_ALERT, "Failed to load file: \"" << path << "\""); + return std::make_tuple(0, (osg::Node*)NULL); } osg::ref_ptr options; @@ -529,6 +533,8 @@ sgLoad3DModel_internal(const SGPath& path, try { readProperties(modelpath, props); } catch (const sg_exception &t) { + simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::XMLModelLoad, + "Failed to load model XML:" + t.getFormattedMessage(), t.getLocation()); SG_LOG(SG_IO, SG_DEV_ALERT, "Failed to load xml: " << t.getFormattedMessage()); throw; @@ -548,9 +554,12 @@ sgLoad3DModel_internal(const SGPath& path, if (props->hasValue("/path")) { string modelPathStr = props->getStringValue("/path"); modelpath = SGModelLib::findDataFile(modelPathStr, NULL, modelDir); - if (modelpath.isNull()) + if (modelpath.isNull()) { + simgear::reportFailure(simgear::LoadFailure::NotFound, simgear::ErrorCode::ThreeDModelLoad, + "Model not found:" + modelPathStr, sg_location{modelPathStr}); throw sg_io_exception("Model file not found: '" + modelPathStr + "'", - path); + path, {}, false); + } if (props->hasValue("/texture-path")) { string texturePathStr = props->getStringValue("/texture-path"); @@ -583,9 +592,13 @@ sgLoad3DModel_internal(const SGPath& path, osgDB::ReaderWriter::ReadResult modelResult; modelResult = osgDB::readRefNodeFile(modelpath.utf8Str(), options.get()); - if (!modelResult.validNode()) + if (!modelResult.validNode()) { + simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::XMLModelLoad, + "Failed to load 3D model:" + modelResult.message(), modelpath); throw sg_io_exception("Failed to load 3D model:" + modelResult.message(), - modelpath); + modelpath, {}, false); + } + model = copyModel(modelResult.getNode()); // Add an extra reference to the model stored in the database. // That is to avoid expiring the object from the cache even if diff --git a/simgear/scene/model/animation.cxx b/simgear/scene/model/animation.cxx index 32e71b46..95e0d003 100644 --- a/simgear/scene/model/animation.cxx +++ b/simgear/scene/model/animation.cxx @@ -39,9 +39,11 @@ #include #include +#include #include #include #include + #include #include #include @@ -454,6 +456,9 @@ SGAnimation::~SGAnimation() } if (!info.empty()) { + reportFailure(LoadFailure::Misconfigured, ErrorCode::XMLModelLoad, + "Could not find at least one of the following object for animation:" + info, + SGPath::fromUtf8(_modelData.getPath())); SG_LOG(SG_IO, SG_DEV_ALERT, "Could not find at least one of the following" " objects for animation: " << info << " in file: " << _modelData.getPath()); } @@ -772,10 +777,16 @@ bool SGAnimation::setCenterAndAxisFromObject(osg::Node *rootNode, SGVec3d& cente object_group->setNodeMask(0); } else { + reportFailure(LoadFailure::Misconfigured, ErrorCode::XMLModelLoad, + "Could not find valid line segment for axis animation:" + axis_object_name, + SGPath::fromUtf8(_modelData.getPath())); SG_LOG(SG_IO, SG_DEV_ALERT, "Could not find a valid line segment for animation: " << axis_object_name << " in file: " << _modelData.getPath()); } } else if (can_warn) { + reportFailure(LoadFailure::Misconfigured, ErrorCode::XMLModelLoad, + "Could not find object for axis animation:" + axis_object_name, + SGPath::fromUtf8(_modelData.getPath())); SG_LOG(SG_IO, SG_DEV_ALERT, "Could not find at least one of the following objects for axis animation: " << axis_object_name << " in file: " << _modelData.getPath()); } } diff --git a/simgear/scene/tgdb/ReaderWriterSTG.cxx b/simgear/scene/tgdb/ReaderWriterSTG.cxx index f7be485e..bdbbc220 100644 --- a/simgear/scene/tgdb/ReaderWriterSTG.cxx +++ b/simgear/scene/tgdb/ReaderWriterSTG.cxx @@ -38,10 +38,12 @@ #include #include -#include -#include #include +#include #include +#include +#include + #include #include #include @@ -650,6 +652,8 @@ struct ReaderWriterSTG::_ModelBin { std::string terrain_name = string("terrain ").append(bucket.gen_index_str()); terrainGroup->setName(terrain_name); + simgear::ErrorReportContext ec{"bucket", bucket.gen_index_str()}; + bool vpb_active = SGSceneFeatures::instance()->getVPBActive(); if (vpb_active) { std::string filename = "vpb/" + bucket.gen_vpb_base() + ".osgb"; diff --git a/simgear/scene/tgdb/SGReaderWriterBTG.cxx b/simgear/scene/tgdb/SGReaderWriterBTG.cxx index fa0a2175..11734805 100644 --- a/simgear/scene/tgdb/SGReaderWriterBTG.cxx +++ b/simgear/scene/tgdb/SGReaderWriterBTG.cxx @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -62,13 +63,15 @@ SGReaderWriterBTG::readNode(const std::string& fileName, const SGReaderWriterOptions* sgOptions; sgOptions = dynamic_cast(options); osg::Node* result = NULL; + simgear::ErrorReportContext ec{"btg", fileName}; try { result = SGLoadBTG(fileName, sgOptions); if (!result) return ReadResult::FILE_NOT_HANDLED; } catch (sg_exception& e) { - SG_LOG(SG_IO, SG_WARN, "error reading:" << fileName << ":" << - e.getFormattedMessage()); + simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::BTGLoad, + "Failed to load BTG file:" + e.getFormattedMessage(), + e.getLocation()); return ReadResult::ERROR_IN_READING_FILE; }