From 88f2392088b791f790237dd920e5b6fa8ac30c4f Mon Sep 17 00:00:00 2001 From: Szemeredi Peter Date: Tue, 1 Sep 2026 22:52:21 +0200 Subject: [PATCH] macOS: don't crash the process when bridge injection fails on a non-scriptable navigation OnDelegateOnDidFinishNavigation unconditionally injects the C#<->JS bridge script via InvokeScript on every finished navigation. When the navigation loaded non-HTML content (e.g. a file/PDF/image download response), WKWebView.evaluateJavaScript fails at the native WebKit level; InvokeScript already converts that into a JavaScriptException, but nothing caught it in this async void handler, so the exception escaped and crashed the whole process instead of just failing that one bridge-injection attempt. Reproduced consistently on macOS (Apple Silicon) with a ChatGPT-generated file download: clicking the download link crashed the process every time, with the app otherwise working correctly (login, session persistence, drag-and-drop upload, and clipboard paste all unaffected). Fix: wrap the InvokeScript call in a try/catch for JavaScriptException. This only stops the crash - it does not add file-download handling (saving, progress, etc.), which is a separate, larger change (decidePolicyForNavigationResponse + WKDownloadDelegate) intentionally left out of this PR; happy to open that as its own follow-up if there's interest. Verified by building this change locally (net8.0 and net10.0 desktop TFMs) and by running AtprismPoc, an Avalonia app that embeds NativeWebView, against a ProjectReference to this patched clone: the same download that reliably crashed the process before no longer does. --- .../Macios/MaciosWebViewAdapter.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Controls.WebView.Core/Macios/MaciosWebViewAdapter.cs b/src/Avalonia.Controls.WebView.Core/Macios/MaciosWebViewAdapter.cs index 5976f53..c036178 100644 --- a/src/Avalonia.Controls.WebView.Core/Macios/MaciosWebViewAdapter.cs +++ b/src/Avalonia.Controls.WebView.Core/Macios/MaciosWebViewAdapter.cs @@ -295,7 +295,19 @@ private void OnDelegateOnDecidePolicyNavigation(object? _, WKNavigationDelegate. private async void OnDelegateOnDidFinishNavigation(object? sender, EventArgs args) { - _ = await InvokeScript(WebViewHelper.BuildWebKitInvokeCSharpActionScript(_scriptHandlerMessageName, stringify: true)); + try + { + _ = await InvokeScript(WebViewHelper.BuildWebKitInvokeCSharpActionScript(_scriptHandlerMessageName, stringify: true)); + } + catch (JavaScriptException) + { + // The just-finished navigation didn't load a scriptable HTML document (e.g. a file + // download, image, or PDF response) - EvaluateJavaScriptAsync then fails at the + // native WebKit level and InvokeScript surfaces that as a JavaScriptException. That + // failure is not fatal on its own: the C#<->JS bridge simply isn't available for this + // particular navigation. Left unguarded, this exception previously escaped this + // async void event handler uncaught and crashed the whole process. + } using var url = _webView.Url; NavigationCompleted?.Invoke(this, new WebViewNavigationCompletedEventArgs { Request = Uri.TryCreate(url!.AbsoluteString, UriKind.Absolute, out var uri) ? uri : null, IsSuccess = true });