diff --git a/cpp/src/error.rs b/cpp/src/error.rs index 3ce9a107..7d97cd14 100644 --- a/cpp/src/error.rs +++ b/cpp/src/error.rs @@ -17,7 +17,7 @@ pub enum VerboseError { CyclicInteractionError(Vec), UndefinedGroupError(String), PluginNotLoadedError(String), - InvalidArgument(String), + InvalidArgument(Box), Other(Box), } @@ -39,7 +39,10 @@ impl std::fmt::Display for VerboseError { write!(f, "UndefinedGroupError: {group}",) } Self::PluginNotLoadedError(plugin) => write!(f, "PluginNotLoadedError: {plugin}"), - Self::InvalidArgument(s) => write!(f, "InvalidArgument: {s}"), + Self::InvalidArgument(e) => { + write!(f, "InvalidArgument: ")?; + fmt_error_chain(e.as_ref(), f) + } Self::Other(e) => fmt_error_chain(e.as_ref(), f), } } @@ -61,7 +64,7 @@ variant_box_from_error!(PluginDataError, VerboseError::Other); impl From for VerboseError { fn from(value: GameHandleCreationError) -> Self { match value { - GameHandleCreationError::NotADirectory(_) => Self::InvalidArgument(value.to_string()), + GameHandleCreationError::NotADirectory(_) => Self::InvalidArgument(Box::new(value)), GameHandleCreationError::LoadOrderError(_) | _ => Self::Other(Box::new(value)), } } @@ -71,7 +74,7 @@ impl From for VerboseError { fn from(value: LoadPluginsError) -> Self { match value { LoadPluginsError::PluginNotLoaded(p) => Self::PluginNotLoadedError(p), - LoadPluginsError::PluginValidationError(_) => Self::InvalidArgument(value.to_string()), + LoadPluginsError::PluginValidationError(_) => Self::InvalidArgument(Box::new(value)), LoadPluginsError::DatabaseLockPoisoned | LoadPluginsError::IoError(_) | LoadPluginsError::PluginDataError(_) diff --git a/cpp/src/tests/api/interface/game_interface_test.h b/cpp/src/tests/api/interface/game_interface_test.h index c8d9b176..1b734d96 100644 --- a/cpp/src/tests/api/interface/game_interface_test.h +++ b/cpp/src/tests/api/interface/game_interface_test.h @@ -286,8 +286,15 @@ TEST_P( TEST_P(GameInterfaceTest, loadPluginsWithANonPluginShouldNotAddItToTheLoadedPlugins) { - ASSERT_THROW(handle_->LoadPlugins({nonPluginFile}, false), - std::invalid_argument); + try { + handle_->LoadPlugins({nonPluginFile}, false); + FAIL(); + } catch (std::invalid_argument& e) { + EXPECT_TRUE(startsWith( + e.what(), "failed validation of input plugin paths: the file at \"")); + EXPECT_TRUE(endsWith( + e.what(), "NotAPlugin.esm\" does not have a valid plugin header")); + } ASSERT_TRUE(handle_->GetLoadedPlugins().empty()); } diff --git a/cpp/src/tests/common_game_test_fixture.h b/cpp/src/tests/common_game_test_fixture.h index b6517793..654a13ea 100644 --- a/cpp/src/tests/common_game_test_fixture.h +++ b/cpp/src/tests/common_game_test_fixture.h @@ -384,6 +384,17 @@ protected: WriteFile(path, bytes); } + static bool startsWith(const std::string& str, const std::string& prefix) { + if (str.length() < prefix.length()) { + return false; + } + + auto view = std::string_view(str); + view.remove_suffix(str.length() - prefix.length()); + + return view == prefix; + } + static bool endsWith(const std::string& str, const std::string& suffix) { if (str.length() < suffix.length()) { return false;