From a9197d52fe9be740fb59d562296f4f26bfef71df Mon Sep 17 00:00:00 2001 From: Kenny Kerr Date: Fri, 13 Mar 2020 20:33:33 -0700 Subject: [PATCH 1/2] hresult_class_not_registered --- strings/base_error.h | 12 +++++++++ strings/base_types.h | 1 + test/test/hresult_class_not_registered.cpp | 30 ++++++++++++++++++++++ test/test/test.vcxproj | 1 + 4 files changed, 44 insertions(+) create mode 100644 test/test/hresult_class_not_registered.cpp diff --git a/strings/base_error.h b/strings/base_error.h index 3890868d8..bfcd925f9 100644 --- a/strings/base_error.h +++ b/strings/base_error.h @@ -376,6 +376,13 @@ WINRT_EXPORT namespace winrt hresult_class_not_available(take_ownership_from_abi_t) noexcept : hresult_error(impl::error_class_not_available, take_ownership_from_abi) {} }; + struct hresult_class_not_registered : hresult_error + { + hresult_class_not_registered() noexcept : hresult_error(impl::error_class_not_registered) {} + hresult_class_not_registered(param::hstring const& message) noexcept : hresult_error(impl::error_class_not_registered, message) {} + hresult_class_not_registered(take_ownership_from_abi_t) noexcept : hresult_error(impl::error_class_not_registered, take_ownership_from_abi) {} + }; + struct hresult_changed_state : hresult_error { hresult_changed_state() noexcept : hresult_error(impl::error_changed_state) {} @@ -453,6 +460,11 @@ WINRT_EXPORT namespace winrt throw hresult_class_not_available(take_ownership_from_abi); } + if (result == impl::error_class_not_registered) + { + throw hresult_class_not_registered(take_ownership_from_abi); + } + if (result == impl::error_changed_state) { throw hresult_changed_state(take_ownership_from_abi); diff --git a/strings/base_types.h b/strings/base_types.h index 131641916..0eadc03cc 100644 --- a/strings/base_types.h +++ b/strings/base_types.h @@ -139,6 +139,7 @@ namespace winrt::impl constexpr hresult error_out_of_bounds{ static_cast(0x8000000B) }; // E_BOUNDS constexpr hresult error_no_interface{ static_cast(0x80004002) }; // E_NOINTERFACE constexpr hresult error_class_not_available{ static_cast(0x80040111) }; // CLASS_E_CLASSNOTAVAILABLE + constexpr hresult error_class_not_registered{ static_cast(0x80040154) }; // REGDB_E_CLASSNOTREG constexpr hresult error_changed_state{ static_cast(0x8000000C) }; // E_CHANGED_STATE constexpr hresult error_illegal_method_call{ static_cast(0x8000000E) }; // E_ILLEGAL_METHOD_CALL constexpr hresult error_illegal_state_change{ static_cast(0x8000000D) }; // E_ILLEGAL_STATE_CHANGE diff --git a/test/test/hresult_class_not_registered.cpp b/test/test/hresult_class_not_registered.cpp new file mode 100644 index 000000000..d1717569a --- /dev/null +++ b/test/test/hresult_class_not_registered.cpp @@ -0,0 +1,30 @@ +#include "pch.h" + +using namespace winrt; +using namespace Windows::Foundation; + +namespace +{ + IAsyncAction Async() + { + // This is just a simple way of testing all of the ABI and projection + // error propagation in one go. + throw hresult_class_not_registered(L"test message"); + } +} +TEST_CASE("hresult_class_not_registered") +{ + REQUIRE(hresult_class_not_registered().message() == L"Class not registered"); + REQUIRE(hresult_class_not_registered().code() == REGDB_E_CLASSNOTREG); + + try + { + Async().get(); + FAIL(L"Previous line should throw"); + } + catch (hresult_class_not_registered const& e) + { + REQUIRE(e.message() == L"test message"); + REQUIRE(e.code() == REGDB_E_CLASSNOTREG); + } +} \ No newline at end of file diff --git a/test/test/test.vcxproj b/test/test/test.vcxproj index 56ca27cb4..de9f484ff 100644 --- a/test/test/test.vcxproj +++ b/test/test/test.vcxproj @@ -330,6 +330,7 @@ + From 0b8a71cc18ebe05a3be3327bf44ef43a08cf90d6 Mon Sep 17 00:00:00 2001 From: Kenny Kerr Date: Mon, 16 Mar 2020 10:41:01 -0700 Subject: [PATCH 2/2] activation --- strings/base_activation.h | 6 +++++- test/old_tests/UnitTests/get_activation_factory.cpp | 12 ++---------- test/test/velocity.cpp | 8 ++++---- test/test_win7/velocity.cpp | 8 ++++---- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/strings/base_activation.h b/strings/base_activation.h index 543bbfb43..7f35e1a79 100644 --- a/strings/base_activation.h +++ b/strings/base_activation.h @@ -55,6 +55,9 @@ namespace winrt::impl return 0; } + com_ptr error_info; + WINRT_IMPL_GetErrorInfo(0, error_info.put_void()); + std::wstring path{ static_cast(name) }; std::size_t count{}; @@ -97,7 +100,8 @@ namespace winrt::impl } } - return error_class_not_available; + WINRT_IMPL_SetErrorInfo(0, error_info.get()); + return hr; } } diff --git a/test/old_tests/UnitTests/get_activation_factory.cpp b/test/old_tests/UnitTests/get_activation_factory.cpp index a3f5a18ba..dcba89b4f 100644 --- a/test/old_tests/UnitTests/get_activation_factory.cpp +++ b/test/old_tests/UnitTests/get_activation_factory.cpp @@ -23,15 +23,7 @@ TEST_CASE("get_activation_factory") } // Calling get_activation_factory with an invalid class name - try - { - get_activation_factory(L"Composable.DoesNotExist"); - REQUIRE(false); - } - catch (hresult_class_not_available const& e) - { - REQUIRE(e.message() == L"Composable.DoesNotExist"); - } + REQUIRE_THROWS_AS(get_activation_factory(L"Composable.DoesNotExist"), hresult_class_not_registered); } TEST_CASE("try_get_activation_factory") @@ -72,6 +64,6 @@ TEST_CASE("try_get_activation_factory") auto factory = try_get_activation_factory(e); REQUIRE(factory == nullptr); REQUIRE(get_error_info() == nullptr); - REQUIRE(e.code() == CLASS_E_CLASSNOTAVAILABLE); + REQUIRE(e.code() == REGDB_E_CLASSNOTREG); } } diff --git a/test/test/velocity.cpp b/test/test/velocity.cpp index b47a3fdfe..0c5ba5370 100644 --- a/test/test/velocity.cpp +++ b/test/test/velocity.cpp @@ -17,24 +17,24 @@ TEST_CASE("velocity") REQUIRE(b == nullptr); // Class1 is always disabled and thus will not activate. - REQUIRE_THROWS_AS(Class1(), hresult_class_not_available); + REQUIRE_THROWS_AS(Class1(), hresult_class_not_registered); // Class2 is always enabled so should activate just fine. Class2 c; c.Class2_Method(); // Class3 is always disabled and thus will not activate. - REQUIRE_THROWS_AS(Class3(), hresult_class_not_available); + REQUIRE_THROWS_AS(Class3(), hresult_class_not_registered); // Class4 is not feature-controlled but uses feature interfaces. Class4 d; d.Class4_Method(); // The single argument constructor is always disabled. - REQUIRE_THROWS_AS(Class4(1), hresult_class_not_available); + REQUIRE_THROWS_AS(Class4(1), hresult_class_not_registered); // The Class4_Static1 static is always disabled. - REQUIRE_THROWS_AS(Class4::Class4_Static1(), hresult_class_not_available); + REQUIRE_THROWS_AS(Class4::Class4_Static1(), hresult_class_not_registered); // The two argument constructor is always enabled. Class4 e(1, 2); diff --git a/test/test_win7/velocity.cpp b/test/test_win7/velocity.cpp index b47a3fdfe..0c5ba5370 100644 --- a/test/test_win7/velocity.cpp +++ b/test/test_win7/velocity.cpp @@ -17,24 +17,24 @@ TEST_CASE("velocity") REQUIRE(b == nullptr); // Class1 is always disabled and thus will not activate. - REQUIRE_THROWS_AS(Class1(), hresult_class_not_available); + REQUIRE_THROWS_AS(Class1(), hresult_class_not_registered); // Class2 is always enabled so should activate just fine. Class2 c; c.Class2_Method(); // Class3 is always disabled and thus will not activate. - REQUIRE_THROWS_AS(Class3(), hresult_class_not_available); + REQUIRE_THROWS_AS(Class3(), hresult_class_not_registered); // Class4 is not feature-controlled but uses feature interfaces. Class4 d; d.Class4_Method(); // The single argument constructor is always disabled. - REQUIRE_THROWS_AS(Class4(1), hresult_class_not_available); + REQUIRE_THROWS_AS(Class4(1), hresult_class_not_registered); // The Class4_Static1 static is always disabled. - REQUIRE_THROWS_AS(Class4::Class4_Static1(), hresult_class_not_available); + REQUIRE_THROWS_AS(Class4::Class4_Static1(), hresult_class_not_registered); // The two argument constructor is always enabled. Class4 e(1, 2);