- Introduced a `Via` field in `ParseError` to indicate the proxy address used during requests, improving clarity on error contexts. - Updated `ProxyPool` to prioritize confirmed live proxies while available, ensuring more reliable proxy selection and reducing connection timeouts. - Implemented fallback logic to allow the use of unconfirmed proxies when no confirmed ones are available, preventing collection stalls. - Adjusted logging in `CollectLogEntryViewModel` to include proxy details, enhancing error visibility for users. - Added unit tests to verify new proxy selection logic and ensure correct behavior under various conditions. These changes improve the robustness of the proxy management system and enhance the overall user experience by providing clearer error messages and more efficient proxy usage.
47 lines
2.5 KiB
C#
47 lines
2.5 KiB
C#
namespace AvParser.Core.Parsing;
|
|
|
|
/// <summary>A recoverable problem with a single record. Parsing continues after one of these.</summary>
|
|
/// <param name="Index">1-based position of the offending item: a line, or a place in a listing.</param>
|
|
/// <param name="Message">What went wrong, phrased for a user rather than a developer.</param>
|
|
public sealed record ParseError(int Index, string Message)
|
|
{
|
|
/// <summary>
|
|
/// Stable identifier for the kind of failure, or <see langword="null"/> when the message is
|
|
/// the only thing on offer.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// The domain stays language-free: it produces an English message plus a code, and the UI
|
|
/// translates <c>Collect.Error.{Code}</c> with <see cref="Arguments"/>, falling back to
|
|
/// <see cref="Message"/>. Without this, a Russian UI would still print English error text —
|
|
/// and moving the strings themselves into the domain would drag localisation down there.
|
|
/// </remarks>
|
|
public string? Code { get; init; }
|
|
|
|
/// <summary>Values to substitute into the translated message.</summary>
|
|
public IReadOnlyList<object?> Arguments { get; init; } = [];
|
|
|
|
/// <summary>What the failure was about — the address or the line it came from.</summary>
|
|
/// <remarks>
|
|
/// Deliberately outside <see cref="Message"/> and <see cref="Arguments"/>: a translated template
|
|
/// has fixed placeholders, so an address cannot be appended to it without editing every
|
|
/// translation. The live collection log prints this beside the translated text, which is the
|
|
/// difference between "the site answered 404" and knowing which of ten thousand ids that was.
|
|
/// </remarks>
|
|
public string? Subject { get; init; }
|
|
|
|
/// <summary>What the attempt went through — a proxy address — when it went through anything.</summary>
|
|
/// <remarks>
|
|
/// Worth carrying for the same reason as <see cref="Subject"/>: "the site answered 404" and "the
|
|
/// request timed out" mean very different things depending on whether the pool handed out a proxy
|
|
/// it had confirmed or one it had never spoken to, and without this the difference is invisible.
|
|
/// </remarks>
|
|
public string? Via { get; init; }
|
|
|
|
/// <summary>Creates an error carrying a translation code.</summary>
|
|
public static ParseError Create(int index, string code, string message, params object?[] arguments) =>
|
|
new(index, message) { Code = code, Arguments = arguments };
|
|
|
|
/// <inheritdoc />
|
|
public override string ToString() => $"#{Index}: {Message}";
|
|
}
|