mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-05-12 01:31:33 -04:00
Catch WebKit load failures on account login. Wrap the code path that opens NativeWebDialog / WebView for Audible login in a try/catch for DllNotFoundException (and related load failures). On failure, show a short dialog: install WebKit2GTK and do not crash the app.
This commit is contained in:
@@ -100,12 +100,44 @@ public class AvaloniaLoginChoiceEager : ILoginChoiceEager
|
||||
dialog.Source = new Uri(shoiceIn.LoginUrl);
|
||||
};
|
||||
|
||||
if (!Configuration.IsLinux && App.MainWindow is TopLevel topLevel)
|
||||
dialog.Show(topLevel);
|
||||
else
|
||||
dialog.Show();
|
||||
// NativeWebDialog can fault on a posted dispatcher job (e.g. missing libwebkit2gtk on Linux), which bypasses a try/catch around Show().
|
||||
void onUnhandledException(object? sender, DispatcherUnhandledExceptionEventArgs e)
|
||||
{
|
||||
if (!WebView2LoginErrorMessage.IsWebView2SignInInfrastructureFailure(e.Exception))
|
||||
return;
|
||||
e.Handled = true;
|
||||
try
|
||||
{
|
||||
dialog.Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
/* ignore */
|
||||
}
|
||||
tcs.TrySetException(e.Exception);
|
||||
}
|
||||
|
||||
return await tcs.Task;
|
||||
Dispatcher.UIThread.UnhandledException += onUnhandledException;
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Configuration.IsLinux && App.MainWindow is TopLevel topLevel)
|
||||
dialog.Show(topLevel);
|
||||
else
|
||||
dialog.Show();
|
||||
}
|
||||
catch (Exception ex) when (WebView2LoginErrorMessage.IsWebView2SignInInfrastructureFailure(ex))
|
||||
{
|
||||
tcs.TrySetException(ex);
|
||||
}
|
||||
|
||||
return await tcs.Task;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Dispatcher.UIThread.UnhandledException -= onUnhandledException;
|
||||
}
|
||||
|
||||
void Dialog_EnvironmentRequested(object? sender, WebViewEnvironmentRequestedEventArgs e)
|
||||
{
|
||||
|
||||
@@ -11,21 +11,56 @@ public static class WebView2LoginErrorMessage
|
||||
{
|
||||
public const string Caption = "Sign-in browser could not start";
|
||||
|
||||
public static string ExplainerBody =>
|
||||
"Libation could not start the in-app sign-in browser. On Windows this uses Microsoft WebView2. "
|
||||
+ "This is a local sign-in or system setup issue — not a failure of the library scan itself.\r\n\r\n"
|
||||
+ "Things to try:\r\n"
|
||||
+ "• On Windows: install or repair the Microsoft Edge WebView2 Runtime from https://developer.microsoft.com/microsoft-edge/webview2/\r\n"
|
||||
+ "• In Libation Settings, try turning off the option to use the embedded browser and use external browser sign-in instead.\r\n"
|
||||
+ "• Check that security software is not blocking Libation or the embedded browser.\r\n"
|
||||
+ "• Ensure your account can write to local app data folders (permissions).\r\n"
|
||||
+ "• If you run as Administrator, try running Libation as a normal user (or the reverse).\r\n\r\n"
|
||||
+ "After sign-in works, use Import again to scan your library.";
|
||||
public static string ExplainerBody
|
||||
{
|
||||
get
|
||||
{
|
||||
const string localIssue =
|
||||
"This is a local sign-in or system setup issue — not a failure of the library scan itself.\r\n\r\n";
|
||||
const string thingsToTry = "Things to try:\r\n";
|
||||
const string settingsBullet =
|
||||
"• In Libation Settings, try turning off the option to use the embedded browser and use external browser sign-in instead.\r\n";
|
||||
const string securityBullet =
|
||||
"• Check that security software is not blocking Libation or the embedded browser.\r\n";
|
||||
const string permissionsBullet =
|
||||
"• Ensure your account can write to local app data folders (permissions).\r\n";
|
||||
const string adminBullet =
|
||||
"• If you run as Administrator, try running Libation as a normal user (or the reverse).\r\n\r\n";
|
||||
const string footer = "After sign-in works, use Import again to scan your library.";
|
||||
|
||||
if (OperatingSystem.IsLinux())
|
||||
{
|
||||
return "Libation could not start the in-app sign-in browser. On Linux this uses WebKit2GTK (native WebKit). "
|
||||
+ localIssue
|
||||
+ thingsToTry
|
||||
+ "• Install WebKit2GTK for your distro (e.g. on Arch: webkit2gtk or webkit2gtk-4.1).\r\n"
|
||||
+ settingsBullet
|
||||
+ securityBullet
|
||||
+ permissionsBullet
|
||||
+ adminBullet
|
||||
+ footer;
|
||||
}
|
||||
|
||||
return "Libation could not start the in-app sign-in browser. On Windows this uses Microsoft WebView2. "
|
||||
+ localIssue
|
||||
+ thingsToTry
|
||||
+ "• On Windows: install or repair the Microsoft Edge WebView2 Runtime from https://developer.microsoft.com/microsoft-edge/webview2/\r\n"
|
||||
+ settingsBullet
|
||||
+ securityBullet
|
||||
+ permissionsBullet
|
||||
+ adminBullet
|
||||
+ footer;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsWebView2SignInInfrastructureFailure(Exception ex)
|
||||
{
|
||||
for (var e = ex; e is not null; e = e.InnerException)
|
||||
{
|
||||
// Gtk / WebView2: missing native WebKit or WebView2 runtime often surfaces as DllNotFoundException (sometimes without a useful stack).
|
||||
if (e is DllNotFoundException dll && IsEmbeddedWebViewNativeDllFailure(dll))
|
||||
return true;
|
||||
|
||||
if (!StackMentionsEmbeddedSignInBrowser(e))
|
||||
continue;
|
||||
|
||||
@@ -40,6 +75,18 @@ public static class WebView2LoginErrorMessage
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gtk WebView (e.g. Avalonia NativeWebDialog on Linux) requires WebKit2GTK; minimal installs omit <c>libwebkit2gtk</c>.
|
||||
/// </summary>
|
||||
private static bool IsEmbeddedWebViewNativeDllFailure(DllNotFoundException e)
|
||||
{
|
||||
if (e.Message.Contains("libwebkit2gtk", StringComparison.OrdinalIgnoreCase)
|
||||
|| e.Message.Contains("webkit2gtk", StringComparison.OrdinalIgnoreCase))
|
||||
return true;
|
||||
|
||||
return StackMentionsEmbeddedSignInBrowser(e);
|
||||
}
|
||||
|
||||
public static bool TryFindInTree(Exception ex, out Exception? match)
|
||||
{
|
||||
Exception? found = null;
|
||||
@@ -70,6 +117,8 @@ public static class WebView2LoginErrorMessage
|
||||
return stack is not null
|
||||
&& (stack.Contains("WebView2", StringComparison.Ordinal)
|
||||
|| stack.Contains("CoreWebView2", StringComparison.Ordinal)
|
||||
|| stack.Contains("NativeWebDialog", StringComparison.Ordinal));
|
||||
|| stack.Contains("NativeWebDialog", StringComparison.Ordinal)
|
||||
|| stack.Contains("GtkWebView", StringComparison.Ordinal)
|
||||
|| stack.Contains("WebViewControlAvalonia", StringComparison.Ordinal));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user