mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 21:31:14 +00:00
5a28f67d33
Replace 9 nearly-identical catch blocks in RegionService.ProcessRegionAsync with a single catch (Exception ex) that delegates to RegionFailureClassifier.Classify, returning a typed (category, errorMessage) pair. Preserves all original error messages stored in region summary files; failure-path call into HandleProcessingFailureAsync is unchanged. Net source delta: -38 lines in RegionService, +71 lines in new RegionFailureClassifier (pure static), +10 unit tests covering each category, precedence, status-code propagation, null guard. Tests: 68 unit (was 58) + 5 smoke + 3 stub-contract integration tests pass. Co-authored-by: Cursor <cursoragent@cursor.com>
71 lines
2.7 KiB
C#
71 lines
2.7 KiB
C#
using SatelliteProvider.Common.Exceptions;
|
|
|
|
namespace SatelliteProvider.Services.RegionProcessing;
|
|
|
|
internal enum RegionFailureCategory
|
|
{
|
|
Timeout,
|
|
ExternalCancellation,
|
|
TaskCanceledOther,
|
|
OperationCanceledOther,
|
|
RateLimit,
|
|
Network,
|
|
Unexpected,
|
|
}
|
|
|
|
internal sealed record RegionFailureClassification(RegionFailureCategory Category, string ErrorMessage);
|
|
|
|
internal static class RegionFailureClassifier
|
|
{
|
|
public const string TimeoutMessage =
|
|
"Processing timed out after 5 minutes. Unable to download tiles within the time limit.";
|
|
|
|
public const string ExternalCancellationMessage =
|
|
"Processing was cancelled externally (likely application shutdown).";
|
|
|
|
public static RegionFailureClassification Classify(
|
|
Exception ex,
|
|
CancellationTokenSource timeoutCts,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(ex);
|
|
ArgumentNullException.ThrowIfNull(timeoutCts);
|
|
|
|
return ex switch
|
|
{
|
|
TaskCanceledException when timeoutCts.IsCancellationRequested
|
|
=> new RegionFailureClassification(RegionFailureCategory.Timeout, TimeoutMessage),
|
|
|
|
TaskCanceledException when cancellationToken.IsCancellationRequested
|
|
=> new RegionFailureClassification(RegionFailureCategory.ExternalCancellation, ExternalCancellationMessage),
|
|
|
|
TaskCanceledException
|
|
=> new RegionFailureClassification(
|
|
RegionFailureCategory.TaskCanceledOther,
|
|
$"Request cancelled or timed out: {ex.Message}. This may indicate HttpClient timeout or network issues."),
|
|
|
|
OperationCanceledException when timeoutCts.IsCancellationRequested
|
|
=> new RegionFailureClassification(RegionFailureCategory.Timeout, TimeoutMessage),
|
|
|
|
OperationCanceledException
|
|
=> new RegionFailureClassification(
|
|
RegionFailureCategory.OperationCanceledOther,
|
|
$"Operation cancelled: {ex.Message}"),
|
|
|
|
RateLimitException
|
|
=> new RegionFailureClassification(
|
|
RegionFailureCategory.RateLimit,
|
|
$"Rate limit exceeded: {ex.Message}. Google Maps API rate limit was reached and retries were exhausted."),
|
|
|
|
HttpRequestException httpEx
|
|
=> new RegionFailureClassification(
|
|
RegionFailureCategory.Network,
|
|
$"Network error (HTTP {httpEx.StatusCode}): {httpEx.Message}. Failed to download tiles from Google Maps."),
|
|
|
|
_ => new RegionFailureClassification(
|
|
RegionFailureCategory.Unexpected,
|
|
$"Unexpected error ({ex.GetType().Name}): {ex.Message}"),
|
|
};
|
|
}
|
|
}
|