mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-06-25 16:02:36 -04:00
Merge pull request #1847 from rmcrackan/rmcrackan/1845-better-non-json
#1845 - improve error message for common VPN blocking errors
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AudibleApi" Version="10.1.5.1" />
|
||||
<PackageReference Include="AudibleApi" Version="10.2.0.1" />
|
||||
<PackageReference Include="Google.Protobuf" Version="3.34.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
using AudibleApi;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AudibleUtilities;
|
||||
|
||||
/// <summary>
|
||||
/// Libation-facing helpers when Audible returns HTML instead of JSON (library scan, catalog, etc.).
|
||||
/// </summary>
|
||||
public static class NonJsonResponseExceptionExtensions
|
||||
{
|
||||
public const string LibraryScanFailedCaption = "Library scan failed";
|
||||
|
||||
private static readonly string[] ThingsToTryBullets =
|
||||
[
|
||||
"Scan again after a few minutes.",
|
||||
"Sign in to Audible in a browser on the same network.",
|
||||
"Disable VPN or proxy and scan again.",
|
||||
"Remove and re-add the account in Libation.",
|
||||
"If it still fails, check the log for Full body: near the error and attach it to a bug report.",
|
||||
];
|
||||
|
||||
public static IEnumerable<string> GetExplainerLines(this NonJsonResponseException ex)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(ex);
|
||||
yield return getIntro(ex);
|
||||
yield return string.Empty;
|
||||
yield return "Things to try:";
|
||||
foreach (var bullet in ThingsToTryBullets)
|
||||
yield return "• " + bullet;
|
||||
}
|
||||
|
||||
public static string GetExplainerBody(this NonJsonResponseException ex)
|
||||
=> string.Join("\r\n", ex.GetExplainerLines());
|
||||
|
||||
public static bool TryFindInTree(Exception ex, out NonJsonResponseException? match)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(ex);
|
||||
NonJsonResponseException? found = null;
|
||||
walk(ex);
|
||||
match = found;
|
||||
return found is not null;
|
||||
|
||||
void walk(Exception? e)
|
||||
{
|
||||
if (e is null || found is not null)
|
||||
return;
|
||||
|
||||
if (e is NonJsonResponseException nonJson)
|
||||
found = nonJson;
|
||||
|
||||
if (found is not null)
|
||||
return;
|
||||
|
||||
if (e is AggregateException agg)
|
||||
{
|
||||
foreach (var inner in agg.InnerExceptions)
|
||||
walk(inner);
|
||||
}
|
||||
|
||||
walk(e.InnerException);
|
||||
}
|
||||
}
|
||||
|
||||
private static string getIntro(NonJsonResponseException ex)
|
||||
=> ex.HtmlTitle is null
|
||||
? "Audible returned an HTML page instead of the expected library data."
|
||||
: $"Audible returned an HTML page ({ex.HtmlTitle}) instead of the expected library data.";
|
||||
}
|
||||
@@ -231,6 +231,14 @@ public partial class MainVM
|
||||
WebView2LoginErrorMessage.Caption,
|
||||
webViewEx);
|
||||
}
|
||||
else if (NonJsonResponseExceptionExtensions.TryFindInTree(ex, out var htmlEx) && htmlEx is not null)
|
||||
{
|
||||
await MessageBox.ShowAdminAlert(
|
||||
MainWindow,
|
||||
htmlEx.GetExplainerBody(),
|
||||
NonJsonResponseExceptionExtensions.LibraryScanFailedCaption,
|
||||
htmlEx);
|
||||
}
|
||||
else
|
||||
{
|
||||
await MessageBox.ShowAdminAlert(
|
||||
|
||||
@@ -443,6 +443,14 @@ public class ProductsDisplayViewModel : ViewModelBase
|
||||
WebView2LoginErrorMessage.Caption,
|
||||
webViewEx);
|
||||
}
|
||||
else if (NonJsonResponseExceptionExtensions.TryFindInTree(ex, out var htmlEx) && htmlEx is not null)
|
||||
{
|
||||
await MessageBox.ShowAdminAlert(
|
||||
null,
|
||||
htmlEx.GetExplainerBody(),
|
||||
NonJsonResponseExceptionExtensions.LibraryScanFailedCaption,
|
||||
htmlEx);
|
||||
}
|
||||
else
|
||||
{
|
||||
await MessageBox.ShowAdminAlert(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using CommandLine;
|
||||
using Dinah.Core;
|
||||
using FileManager;
|
||||
using AudibleUtilities;
|
||||
using LibationFileManager;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -44,6 +45,15 @@ public abstract class OptionsBase
|
||||
catch (Exception ex)
|
||||
{
|
||||
Environment.ExitCode = (int)ExitCode.RunTimeError;
|
||||
|
||||
if (NonJsonResponseExceptionExtensions.TryFindInTree(ex, out var htmlEx) && htmlEx is not null)
|
||||
{
|
||||
foreach (var line in htmlEx.GetExplainerLines())
|
||||
Console.Error.WriteLine(line);
|
||||
Serilog.Log.Logger.Error(htmlEx, "Audible returned HTML instead of JSON");
|
||||
return;
|
||||
}
|
||||
|
||||
PrintVerbUsage(
|
||||
"ERROR",
|
||||
"=====",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AudibleApi" Version="10.1.5.1" />
|
||||
<PackageReference Include="AudibleApi" Version="10.2.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.7" />
|
||||
<PackageReference Include="NameParserSharp" Version="1.5.0" />
|
||||
<PackageReference Include="Serilog.Exceptions" Version="8.4.0" />
|
||||
|
||||
@@ -96,6 +96,14 @@ public partial class Form1
|
||||
WebView2LoginErrorMessage.Caption,
|
||||
webViewEx);
|
||||
}
|
||||
else if (NonJsonResponseExceptionExtensions.TryFindInTree(ex, out var htmlEx) && htmlEx is not null)
|
||||
{
|
||||
MessageBoxLib.ShowAdminAlert(
|
||||
this,
|
||||
htmlEx.GetExplainerBody(),
|
||||
NonJsonResponseExceptionExtensions.LibraryScanFailedCaption,
|
||||
htmlEx);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBoxLib.ShowAdminAlert(
|
||||
|
||||
@@ -14,6 +14,15 @@ There are two possible causes of this error.
|
||||
1. [Run hangover](#how-to-run-the-hangover-app) and execute the following command in the "Database" tab: `PRAGMA journal_mode=DELETE`
|
||||
2. run this command in your terminal: `sqlite3 "path/to/libation/files/LibationContext.db" "PRAGMA journal_mode=DELETE;"`
|
||||
|
||||
## Library scan fails ("Unexpected character" or "HTML instead of JSON")
|
||||
|
||||
Audible returned an HTML page instead of JSON. Common causes: transient outage, expired login, VPN/proxy, or rate limiting. What to try:
|
||||
|
||||
1. Scan again after a few minutes.
|
||||
2. Sign in to Audible in a browser on the same network.
|
||||
3. Disable VPN/proxy and scan again.
|
||||
4. Remove and re-add the account in Libation.
|
||||
|
||||
## How to run the Hangover App
|
||||
|
||||
When troubleshooting, you may be asked to run 'Hangover'. Hangover is a debugging app to help diagnose and solve some problems with Libation.
|
||||
|
||||
Reference in New Issue
Block a user