Skip to content

Win32: surface the real error when opening a URL fails#36

Open
bkaradzic-microsoft wants to merge 2 commits into
BabylonJS:mainfrom
bkaradzic-microsoft:fix-win32-url-open-diagnostics
Open

Win32: surface the real error when opening a URL fails#36
bkaradzic-microsoft wants to merge 2 commits into
BabylonJS:mainfrom
bkaradzic-microsoft:fix-win32-url-open-diagnostics

Conversation

@bkaradzic-microsoft

Copy link
Copy Markdown
Member

Problem

UrlRequest::Impl::Open (Windows backend) constructs a WinRT Foundation::Uri:

m_uri = Foundation::Uri{winrt::to_hstring(url)};

When the input is not a valid/supported URL, Foundation::Uri throws a winrt::hresult_error, which is not a std::exception. Downstream consumers such as the JsRuntimeHost XMLHttpRequest polyfill only catch std::exception, so the error falls through to a generic catch (...) and is reported as an opaque:

Unknown error opening URL

There is no message and no HRESULT, so these failures are impossible to triage from the JS side.

SendAsync (Win32) had the same problem in the other direction — it swallowed winrt::hresult_error entirely (catch (winrt::hresult_error) { ... }), discarding the message and HRESULT.

Fix

  • UrlRequest_Windows_Shared.h (Impl::Open) — wrap the Foundation::Uri construction in a try/catch that converts the winrt::hresult_error into a std::runtime_error including the offending URL, the system message, and the HRESULT. This routes through the polyfill's existing catch (const std::exception&) so JS reports the real reason.
  • UrlRequest_Win32.cpp (SendAsync) — keep the status-0 (client-side error) contract, but record the WinRT message + HRESULT into StatusText instead of discarding it, so send-time failures are diagnosable via xhr.statusText.

No behavioral change on the success path; this only improves error reporting.

Real-world impact

While triaging a batch of Babylon Native asset-loading failures that all reported the useless Unknown error opening URL, this change immediately surfaced the true cause. For example:

Unable to open URL 'import createSpzModule from 'https://unpkg.com/@adobe/spz@0.2.2/dist/spz.js';
': The parameter is incorrect. (HRESULT 0x80070057)

The "URL" is actually a JavaScript dynamic-import statement being passed to XHR.open() — an entirely different problem than a network/transport error, and one that was completely hidden before this change.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

UrlRequest::Impl::Open constructs a WinRT Foundation::Uri, which throws a winrt::hresult_error (not a std::exception) when the input is not a valid, supported URL. Callers such as the JsRuntimeHost XMLHttpRequest polyfill only catch std::exception, so the real failure was collapsed into a generic `Unknown error opening URL` with no HRESULT or message -- making these failures impossible to triage.

Convert the hresult_error into a std::runtime_error that includes the offending URL, the system message, and the HRESULT, so the polyfill's existing catch (const std::exception&) reports the real reason.

Also stop silently discarding the hresult_error in SendAsync: keep the status-0 (client-side error) contract but record the message/HRESULT into StatusText so send-time failures are diagnosable too.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves diagnostics in the Windows (Win32) URL request backend by preserving WinRT hresult_error details (message + HRESULT) when URL parsing or send-time operations fail, so downstream consumers (notably JS XMLHttpRequest) can surface actionable failure reasons instead of generic “unknown” errors.

Changes:

  • Wrap WinRT Foundation::Uri construction in UrlRequest::Impl::Open with a winrt::hresult_error catch that rethrows as std::runtime_error containing the URL, message, and HRESULT.
  • Update Win32 SendAsync to capture WinRT exception details into m_statusText (keeping the status code 0 contract) instead of discarding them.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
Source/UrlRequest_Windows_Shared.h Converts WinRT URI-construction failures into std::runtime_error with detailed context (URL + message + HRESULT).
Source/UrlRequest_Win32.cpp Preserves WinRT send-time failure details by writing message + HRESULT into StatusText rather than swallowing the exception silently.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Source/UrlRequest_Win32.cpp Outdated
…Text

Address review feedback: transport-level failures should be recorded through the public SetError API (ErrorString/ErrorSymbol/ErrorCode), consistent with the curl (Unix) and NSURL (Apple) backends, rather than written into StatusText -- which is documented as the HTTP reason phrase. The status code still stays 0 (client-side error), preserving the existing contract.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment on lines +67 to +69
std::ostringstream message;
message << "Unable to open URL '" << url << "': " << winrt::to_string(error.message())
<< " (HRESULT 0x" << std::hex << std::uppercase << static_cast<uint32_t>(error.code()) << ")";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants