# Refactor: consolidate 9-way catch ladder in RegionService.ProcessRegionAsync

**Task**: AZ-359_refactor_consolidate_region_catch_ladder
**Name**: Single catch + classifier in region processing
**Description**: Replace the nine near-identical catch blocks with a single `try/catch (Exception ex)` that delegates to a `ClassifyRegionFailure` helper.
**Complexity**: 3 points
**Dependencies**: None
**Component**: Services.RegionProcessing
**Tracker**: AZ-359
**Epic**: AZ-350

## Problem

`SatelliteProvider.Services.RegionProcessing/RegionService.cs:148-197` contains nine catch blocks (TaskCanceledException × 3, OperationCanceledException × 2, RateLimitException, HttpRequestException, Exception × 1) that each build an `errorMessage` and call `HandleProcessingFailureAsync`. Adding a new failure category requires touching all nine.

## Outcome

- One catch block; one classification helper.
- Same observable failure-path behavior preserved for all current categories (timeout, rate-limit, cancellation, generic).
- 37 unit + 5 smoke tests stay green.

## Scope

### Included
- Extract `ClassifyRegionFailure(Exception ex, CancellationTokenSource timeoutCts, CancellationToken cancellationToken) : (FailureCategory, string message)`.
- Replace the catch ladder with a single `catch (Exception ex)` that calls the helper and then `HandleProcessingFailureAsync`.
- Unit-test the classifier directly (cheaper than driving the full processing path).

### Excluded
- Changing the failure categories themselves.
- Adding new categories (deferred to future feature work).

## Acceptance Criteria

**AC-1: Each known exception still classifies correctly**
Given each of the previously-handled exception types (TaskCanceledException after timeout, after user cancel, OperationCanceledException, RateLimitException, HttpRequestException, generic Exception)
When `ClassifyRegionFailure` is called with that exception + the appropriate token state
Then it returns the same human message and category that the old catch block produced.

**AC-2: HandleProcessingFailureAsync called once**
Given any failure
When the catch block runs
Then `HandleProcessingFailureAsync` is called exactly once.

**AC-3: Tests stay green**
Given the post-refactor build
When `scripts/run-tests.sh --smoke` runs
Then all 37 unit + 5 smoke scenarios pass; `RegionTests` (timeout + rate-limit coverage) is unchanged.

## Constraints

- Same observable behavior for all currently-tested failure categories.

## Risks & Mitigation

**Risk 1: subtle category drift**
- *Risk*: a refactor may change which token (timeout vs user) was the cancellation source.
- *Mitigation*: the classifier takes the `timeoutCts` explicitly so it can disambiguate.

Full change entry: `_docs/04_refactoring/03-code-quality-refactoring/list-of-changes.md` (C07).
