diff --git a/src/backend/game/game_settings.h b/src/backend/game/game_settings.h index ebe58b70..a5189ede 100644 --- a/src/backend/game/game_settings.h +++ b/src/backend/game/game_settings.h @@ -104,8 +104,12 @@ namespace YAML { } static bool decode(const Node& node, loot::GameSettings& rhs) { - if (!node.IsMap() || !node["folder"] || !node["type"]) - return false; + if (!node.IsMap()) + throw RepresentationException(node.Mark(), "bad conversion: 'game settings' object must be a map"); + if (!node["folder"]) + throw RepresentationException(node.Mark(), "bad conversion: 'folder' key missing from 'game settings' object"); + if (!node["type"]) + throw RepresentationException(node.Mark(), "bad conversion: 'type' key missing from 'game settings' object"); if (node["type"].as() == loot::GameSettings(loot::GameSettings::tes4).FolderName()) rhs = loot::GameSettings(loot::GameSettings::tes4, node["folder"].as()); @@ -116,7 +120,7 @@ namespace YAML { else if (node["type"].as() == loot::GameSettings(loot::GameSettings::fonv).FolderName()) rhs = loot::GameSettings(loot::GameSettings::fonv, node["folder"].as()); else - return false; + throw RepresentationException(node.Mark(), "bad conversion: invalid value for 'type' key in 'game settings' object"); if (node["name"]) rhs.SetName(node["name"].as()); diff --git a/src/backend/helpers/yaml_set_helpers.h b/src/backend/helpers/yaml_set_helpers.h index 35a686b0..e86ba420 100644 --- a/src/backend/helpers/yaml_set_helpers.h +++ b/src/backend/helpers/yaml_set_helpers.h @@ -43,12 +43,12 @@ namespace YAML { static bool decode(const Node& node, std::set& rhs) { if (!node.IsSequence()) - return false; + throw RepresentationException(node.Mark(), "bad conversion: set must be a sequence of elements"); rhs.clear(); for (const auto &element : node) { if (!rhs.insert(element.template as()).second) - return false; + throw RepresentationException(node.Mark(), "bad conversion: set elements must be unique"); } return true; } @@ -77,12 +77,12 @@ namespace YAML { static bool decode(const Node& node, std::unordered_set& rhs) { if (!node.IsSequence()) - return false; + throw RepresentationException(node.Mark(), "bad conversion: unordered set must be a sequence of elements"); rhs.clear(); for (const auto &element : node) { if (!rhs.insert(element.template as()).second) - return false; + throw RepresentationException(node.Mark(), "bad conversion: unordered set elements must be unique"); } return true; } diff --git a/src/backend/metadata/file.h b/src/backend/metadata/file.h index cdd68c97..e6ed2a8e 100644 --- a/src/backend/metadata/file.h +++ b/src/backend/metadata/file.h @@ -66,11 +66,11 @@ namespace YAML { static bool decode(const Node& node, loot::File& rhs) { if (!node.IsMap() && !node.IsScalar()) - return false; + throw RepresentationException(node.Mark(), "bad conversion: 'file' object must be a map or scalar"); if (node.IsMap()) { if (!node["name"]) - return false; + throw RepresentationException(node.Mark(), "bad conversion: 'name' key missing from 'file' map object"); std::string name = node["name"].as(); std::string condition, display; diff --git a/src/backend/metadata/location.h b/src/backend/metadata/location.h index a32e57bd..f82661b8 100644 --- a/src/backend/metadata/location.h +++ b/src/backend/metadata/location.h @@ -62,14 +62,14 @@ namespace YAML { static bool decode(const Node& node, loot::Location& rhs) { if (!node.IsMap() && !node.IsScalar()) - return false; + throw RepresentationException(node.Mark(), "bad conversion: 'location' object must be a map or scalar"); std::string url; std::string name; if (node.IsMap()) { if (!node["link"]) - return false; + throw RepresentationException(node.Mark(), "bad conversion: 'link' key missing from 'location' map object"); url = node["link"].as(); if (node["name"]) diff --git a/src/backend/metadata/message.h b/src/backend/metadata/message.h index f0b84663..a2e21337 100644 --- a/src/backend/metadata/message.h +++ b/src/backend/metadata/message.h @@ -86,8 +86,12 @@ namespace YAML { } static bool decode(const Node& node, loot::Message& rhs) { - if (!node.IsMap() || !node["type"] || !node["content"]) - return false; + if (!node.IsMap()) + throw RepresentationException(node.Mark(), "bad conversion: 'message' object must be a map"); + if (!node["type"]) + throw RepresentationException(node.Mark(), "bad conversion: 'type' key missing from 'message' object"); + if (!node["content"]) + throw RepresentationException(node.Mark(), "bad conversion: 'content' key missing from 'message' object"); std::string type; type = node["type"].as(); @@ -113,7 +117,7 @@ namespace YAML { found = true; } if (!found) - return false; + throw RepresentationException(node.Mark(), "bad conversion: multilingual messages must contain an English content string"); } // Make any substitutions at this point. diff --git a/src/backend/metadata/message_content.h b/src/backend/metadata/message_content.h index a36f0aff..ccd90d7b 100644 --- a/src/backend/metadata/message_content.h +++ b/src/backend/metadata/message_content.h @@ -59,8 +59,12 @@ namespace YAML { } static bool decode(const Node& node, loot::MessageContent& rhs) { - if (!node.IsMap() || !node["str"] || !node["lang"]) - return false; + if (!node.IsMap()) + throw RepresentationException(node.Mark(), "bad conversion: 'message content' object must be a map"); + if (!node["str"]) + throw RepresentationException(node.Mark(), "bad conversion: 'str' key missing from 'message content' object"); + if (!node["lang"]) + throw RepresentationException(node.Mark(), "bad conversion: 'lang' key missing from 'message content' object"); std::string str = node["str"].as(); unsigned int lang = loot::Language(node["lang"].as()).Code(); diff --git a/src/backend/metadata/plugin_dirty_info.h b/src/backend/metadata/plugin_dirty_info.h index 6d6f7846..195f6af4 100644 --- a/src/backend/metadata/plugin_dirty_info.h +++ b/src/backend/metadata/plugin_dirty_info.h @@ -75,8 +75,12 @@ namespace YAML { } static bool decode(const Node& node, loot::PluginDirtyInfo& rhs) { - if (!node.IsMap() || !node["crc"] || !node["util"]) - return false; + if (!node.IsMap()) + throw RepresentationException(node.Mark(), "bad conversion: 'dirty info' object must be a map"); + if (!node["crc"]) + throw RepresentationException(node.Mark(), "bad conversion: 'crc' key missing from 'dirty info' object"); + if (!node["util"]) + throw RepresentationException(node.Mark(), "bad conversion: 'util' key missing from 'dirty info' object"); uint32_t crc = node["crc"].as(); int itm = 0, ref = 0, nav = 0; diff --git a/src/backend/metadata/plugin_metadata.h b/src/backend/metadata/plugin_metadata.h index 689cecc2..95da590c 100644 --- a/src/backend/metadata/plugin_metadata.h +++ b/src/backend/metadata/plugin_metadata.h @@ -153,8 +153,10 @@ namespace YAML { } static bool decode(const Node& node, loot::PluginMetadata& rhs) { - if (!node.IsMap() || !node["name"]) - return false; + if (!node.IsMap()) + throw RepresentationException(node.Mark(), "bad conversion: 'plugin metadata' object must be a map"); + if (!node["name"]) + throw RepresentationException(node.Mark(), "bad conversion: 'name' key missing from 'plugin metadata' object"); rhs = loot::PluginMetadata(node["name"].as()); @@ -178,7 +180,7 @@ namespace YAML { rhs.Tags(node["tag"].as< std::set >()); if (node["dirty"]) { if (rhs.IsRegexPlugin()) - return false; + throw RepresentationException(node.Mark(), "bad conversion: 'dirty' key must not be present in a regex 'plugin metadata' object"); else rhs.DirtyInfo(node["dirty"].as< std::set >()); } diff --git a/src/backend/metadata/tag.h b/src/backend/metadata/tag.h index 2f6c07a7..6676cad4 100644 --- a/src/backend/metadata/tag.h +++ b/src/backend/metadata/tag.h @@ -63,12 +63,12 @@ namespace YAML { static bool decode(const Node& node, loot::Tag& rhs) { if (!node.IsMap() && !node.IsScalar()) - return false; + throw RepresentationException(node.Mark(), "bad conversion: 'tag' object must be a map or scalar"); std::string condition, tag; if (node.IsMap()) { if (!node["name"]) - return false; + throw RepresentationException(node.Mark(), "bad conversion: 'name' key missing from 'tag' map object"); tag = node["name"].as(); if (node["condition"])