Files
Libation/Source/ApplicationServices/LibraryScanIncompleteException.cs
T
Cursor Agentandrmcrackan 240454efa8 bugfix: don't offer to remove books based on a scan that failed
scanAccountsAsync swallows a per-account failure so the remaining accounts can
still scan. That is right for importing, which only adds and updates, but
FindInactiveBooks treats whatever came back as the whole library and reports
every un-liberated book missing from it as no longer in the account. For a
single-account user a login or network failure therefore yields an empty scan,
and 'Remove Books' pre-checks the entire un-liberated library. ImportAccountAsync
already guards itself with 'if (totalCount == 0) return default;'; this path had
no equivalent.

Track which accounts failed and refuse to identify inactive books when any did,
or when a scan returns nothing while books are at stake. Both grids already
catch and report a failed scan with 'Error scanning library. You may still
manually select books to remove', so throwing lands in the right place and
leaves nothing checked.

Also log how many books the scan found absent, so the count behind a removal
prompt is visible after the fact.

Co-authored-by: rmcrackan <rmcrackan@gmail.com>
2026-08-18 17:58:51 +00:00

31 lines
1.3 KiB
C#

using Dinah.Core;
using System;
using System.Collections.Generic;
namespace ApplicationServices;
/// <summary>
/// A library scan finished without throwing but cannot be trusted to say what is no longer in the account.
/// Deciding "inactive" from such a scan would offer to remove books the user still owns.
/// </summary>
public class LibraryScanIncompleteException : Exception
{
/// <summary>Accounts that could not be scanned, if that is why the scan is untrustworthy.</summary>
public IReadOnlyCollection<string> FailedAccounts { get; }
public LibraryScanIncompleteException(string message, IReadOnlyCollection<string>? failedAccounts = null)
: base(message)
=> FailedAccounts = failedAccounts ?? [];
internal static LibraryScanIncompleteException ForFailedAccounts(IReadOnlyCollection<string> failedAccounts)
=> new(
$"{"account".PluralizeWithCount(failedAccounts.Count)} could not be scanned, so Libation cannot tell which books are no longer in your library: "
+ string.Join(", ", failedAccounts),
failedAccounts);
internal static LibraryScanIncompleteException ForEmptyScan(int existingBookCount)
=> new(
$"The library scan returned no books while Libation still holds {"book".PluralizeWithCount(existingBookCount)}. "
+ "Treating that as an empty Audible library would offer to remove books you still own.");
}