diff --git a/Source/UrlRequest_Win32.cpp b/Source/UrlRequest_Win32.cpp index 2420b20..b179663 100644 --- a/Source/UrlRequest_Win32.cpp +++ b/Source/UrlRequest_Win32.cpp @@ -38,9 +38,15 @@ namespace UrlLib return LoadHttpAsync(); } } - catch (winrt::hresult_error) + catch (const winrt::hresult_error& error) { - // Catch WinRT exceptions, but retain the default status code of 0 to indicate a client side error. + // Retain the default status code of 0 to indicate a client-side (transport) + // error, but record the WinRT failure via SetError -- consistent with the + // curl/NSURL backends -- so it is diagnosable through + // ErrorString()/ErrorSymbol()/ErrorCode() instead of being silently discarded. + std::ostringstream symbol; + symbol << "0x" << std::hex << std::uppercase << static_cast(error.code()); + SetError("winrt", symbol.str(), static_cast(error.code()), winrt::to_string(error.message())); return arcana::task_from_result(); } } diff --git a/Source/UrlRequest_Windows_Shared.h b/Source/UrlRequest_Windows_Shared.h index 2d04b5a..02a2ec5 100644 --- a/Source/UrlRequest_Windows_Shared.h +++ b/Source/UrlRequest_Windows_Shared.h @@ -1,5 +1,6 @@ #include "UrlRequest_Base.h" +#include #include #include #include @@ -53,7 +54,21 @@ namespace UrlLib #endif m_method = method; - m_uri = Foundation::Uri{winrt::to_hstring(url)}; + try + { + m_uri = Foundation::Uri{winrt::to_hstring(url)}; + } + catch (const winrt::hresult_error& error) + { + // Foundation::Uri rejects some inputs (e.g. malformed or unsupported URLs) + // by throwing a WinRT hresult_error, which is not a std::exception. Rethrow + // as std::runtime_error so callers (e.g. the XMLHttpRequest polyfill) surface + // the real reason instead of a generic "Unknown error opening URL". + std::ostringstream message; + message << "Unable to open URL '" << url << "': " << winrt::to_string(error.message()) + << " (HRESULT 0x" << std::hex << std::uppercase << static_cast(error.code()) << ")"; + throw std::runtime_error{message.str()}; + } } arcana::task SendAsync();