Skip to content

Commit dead82f

Browse files
authored
to_message() function extracts exception text from catch(...) (#857)
1 parent 0835afb commit dead82f

File tree

4 files changed

+83
-0
lines changed

4 files changed

+83
-0
lines changed

strings/base_error.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,31 @@ WINRT_EXPORT namespace winrt
546546
}
547547
}
548548

549+
inline __declspec(noinline) hstring to_message()
550+
{
551+
if (winrt_to_message_handler)
552+
{
553+
return winrt_to_message_handler(WINRT_IMPL_RETURNADDRESS());
554+
}
555+
556+
try
557+
{
558+
throw;
559+
}
560+
catch (hresult_error const& e)
561+
{
562+
return e.message();
563+
}
564+
catch (std::exception const& ex)
565+
{
566+
return to_hstring(ex.what());
567+
}
568+
catch (...)
569+
{
570+
std::terminate();
571+
}
572+
}
573+
549574
[[noreturn]] inline void throw_last_error()
550575
{
551576
throw_hresult(impl::hresult_from_win32(WINRT_IMPL_GetLastError()));

strings/base_extern.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
__declspec(selectany) int32_t(__stdcall* winrt_to_hresult_handler)(void* address) noexcept {};
3+
__declspec(selectany) winrt::hstring(__stdcall* winrt_to_message_handler)(void* address) {};
34
__declspec(selectany) void(__stdcall* winrt_throw_hresult_handler)(uint32_t lineNumber, char const* fileName, char const* functionName, void* returnAddress, winrt::hresult const result) noexcept {};
45
__declspec(selectany) void(__stdcall* winrt_suspend_handler)(void const* token) noexcept {};
56
__declspec(selectany) void(__stdcall* winrt_resume_handler)(void const* token) noexcept {};

test/old_tests/UnitTests/hresult_error.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,3 +556,23 @@ TEST_CASE("hresult, std abi support")
556556
}
557557
}
558558

559+
TEST_CASE("hresult, to_message")
560+
{
561+
try
562+
{
563+
throw std::out_of_range("oh no, out of range");
564+
}
565+
catch (...)
566+
{
567+
REQUIRE(to_message() == L"oh no, out of range");
568+
}
569+
570+
try
571+
{
572+
throw hresult_error(E_HANDLE, L"oh no, invalid handle");
573+
}
574+
catch (...)
575+
{
576+
REQUIRE(to_message() == L"oh no, invalid handle");
577+
}
578+
}

test/test/custom_error.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,24 @@ namespace
3737
return 0;
3838
}
3939

40+
// Global handler to translate custom exception to message
41+
hstring __stdcall message_handler(void* address)
42+
{
43+
REQUIRE(address);
44+
45+
try
46+
{
47+
throw;
48+
}
49+
catch (CustomError)
50+
{
51+
return L"a custom error";
52+
}
53+
54+
REQUIRE(false);
55+
return {};
56+
}
57+
4058
static bool s_loggerCalled = false;
4159

4260
void __stdcall logger(uint32_t lineNumber, char const* fileName, char const* functionName, void* returnAddress, winrt::hresult const result) noexcept
@@ -77,3 +95,22 @@ TEST_CASE("custom_error_logger")
7795
winrt_throw_hresult_handler = nullptr;
7896
s_loggerCalled = false;
7997
}
98+
99+
TEST_CASE("custom_error_message")
100+
{
101+
// Set up global handler
102+
REQUIRE(!winrt_to_message_handler);
103+
winrt_to_message_handler = message_handler;
104+
105+
try
106+
{
107+
throw CustomError();
108+
}
109+
catch (...)
110+
{
111+
REQUIRE(to_message() == L"a custom error");
112+
}
113+
114+
// Remove global handler
115+
winrt_to_message_handler = nullptr;
116+
}

0 commit comments

Comments
 (0)