# 83 — BPC_ErrorHandler

## Blueprint Spec — UE 5.5–5.7

---

### Parent Class
`ActorComponent`

### Dependencies
- [`SS_SaveManager`](../05-saveload/28_SS_SaveManager.md) — Save state on error
- [`BPC_LoadingScreen`](../11-polish/76_BPC_LoadingScreen.md) — Error screen display
- [`BPC_AnalyticsTracker`](../11-polish/82_BPC_AnalyticsTracker.md) — Error telemetry
- [`WBP_ErrorScreen`](../06-ui/49_WBP_ErrorScreen.md) — UI display (Phase 5)
- [`BPC_LogManager`](../01-core/06_BPC_LogManager.md) — Logging (Phase 0)

### Purpose
Centralized error handling and crash recovery system. Traps and classifies runtime errors across all game systems, displays user-friendly error messages, attempts automatic recovery when possible, and provides fallback behaviors for non-critical failures. Supports error severity levels, recovery strategies, and persistent error logging. Prevents cascading failures by isolating errors to their originating system.

### Enums

**EErrorSeverity**

| Value | Description |
|-------|-------------|
| Info | Non-critical, no action needed |
| Warning | Minor issue, gameplay continues |
| Error | Feature degraded, auto-recovery attempted |
| Critical | Game cannot continue, autosave + return to menu |
| Fatal | Crash/immediate shutdown |

**EErrorSource**

| Value | Description |
|-------|-------------|
| System | Core framework error |
| SaveLoad | Save/load corruption |
| Asset | Missing or corrupted asset |
| Network | Network failure |
| AI | AI system error |
| Audio | Audio system error |
| UI | Widget error |
| Input | Input handling error |
| Performance | Out of memory, hitch |
| Unknown | Unclassified |

**ERecoveryAction**

| Value | Description |
|-------|-------------|
| None | No recovery needed |
| Retry | Retry failed operation |
| ResetSystem | Reinitialize subsystem |
| ReloadLevel | Reload current level |
| LoadLastSave | Load last checkpoint |
| FallbackDefault | Use default values |
| Terminate | End game session |

### Structs

**FErrorEntry**

| Field | Type | Description |
|-------|------|-------------|
| ErrorID | FName | Unique error identifier |
| Severity | EErrorSeverity | Error level |
| Source | EErrorSource | Originating system |
| Message | FText | User-friendly description |
| TechnicalDetails | FString | Developer details |
| RecoveryAction | ERecoveryAction | Attempted recovery |
| bRecoverySuccessful | Bool | Recovery outcome |
| Timestamp | Float | When error occurred |
| ContextData | TMap\<FName, FString\> | Error context |

**FErrorThreshold**

| Field | Type | Description |
|-------|------|-------------|
| Source | EErrorSource | Error category |
| MaxRetries | Int32 | Attempts before escalation |
| RetryWindow | Float | Cooldown in seconds |
| CurrentRetries | Int32 | Current attempt count |
| LastErrorTime | Float | Last occurrence |

### Variables

| Name | Type | Description |
|------|------|-------------|
| `bErrorHandlingEnabled` | Bool | Master toggle |
| `ErrorLog` | TArray\<FErrorEntry\> | Persistent error history |
| `ActiveError` | FErrorEntry | Current unhandled error |
| `ErrorThresholds` | TMap\<EErrorSource, FErrorThreshold\> | Retry limits |
| `bShowingErrorScreen` | Bool | UI displayed |
| `bAutosaveOnError` | Bool | Save on critical error |
| `bLogErrorsToFile` | Bool | Write error log |
| `MaxLogSize` | Int32 | Error history cap (100) |
| `RecoveryCallbacks` | TMap\<EErrorSource, Delegate\> | System recovery handlers |

### Functions

| Name | Inputs | Outputs | Description |
|------|--------|---------|-------------|
| `Initialize` | — | — | Register default recovery handlers |
| `HandleError` | Error: FErrorEntry | — | Process error entry |
| `RegisterRecoveryHandler` | Source: EErrorSource, Callback: Delegate | — | Set recovery function |
| `AttemptRecovery` | Error: FErrorEntry | Bool | Try to fix error |
| `ShowErrorScreen` | Error: FErrorEntry | — | Display error UI |
| `DismissErrorScreen` | — | — | Close error UI |
| `LogError` | Error: FErrorEntry | — | Add to error log |
| `GetErrorHistory` | Source: EErrorSource | TArray\<FErrorEntry\> | Filter errors |
| `GetLastError` | — | FErrorEntry | Most recent error |
| `ClearErrorLog` | — | — | Reset error history |
| `CheckThreshold` | Source: EErrorSource | Bool | Retry limit reached |
| `ResetThreshold` | Source: EErrorSource | — | Reset retry counter |
| `HandleFatalError` | Error: FErrorEntry | — | Autosave + quit |
| `RecoverSystem` | Source: EErrorSource | Bool | Reinitialize system |
| `ReloadLevel` | — | — | Reload current level |
| `LoadLastSave` | — | — | Rollback to save |
| `RegisterSystemHealthCheck` | Name: FName, CheckFunc: Delegate | — | Periodic health |

### Blueprint Flow

```
[Initialize]
  └─► Register default recovery handlers:
         EErrorSource.SaveLoad -> AttemptReadBackup()
         EErrorSource.Asset -> LoadFallbackAsset()
         EErrorSource.AI -> ResetAIDirector()
         EErrorSource.Audio -> RebuildAudioEngine()
         EErrorSource.UI -> RebuildWidgetTree()
         EErrorSource.Input -> RebindInputContext()
  └─► Start periodic health check timer (every 30 seconds)
  └─► bErrorHandlingEnabled = true
  └─► MaxLogSize = 100

[HandleError]
  └─► If Not bErrorHandlingEnabled: return (minimal logging via BPC_LogManager)
  └─► Error.Timestamp = GetGameTimeInSeconds()
  └─► LogError(Error)
  └─► CheckThreshold(Error.Source):
         If threshold exceeded:
              Escalate severity one level
              ResetThreshold(Error.Source)
  └─► Switch Error.Severity:
         Info: Log only, no action
         Warning: Log + broadcast OnErrorOccurred
         Error: Log + AttemptRecovery() + ShowErrorScreen if recovery fails
         Critical: Autosave + AttemptRecovery() + LoadingScreen + Back to menu
         Fatal: Autosave + ShowErrorScreen + Quit game after timer

[AttemptRecovery]
  └─► GetRecoveryHandler(Error.Source)
  └─► If handler exists:
         Execute handler
         Error.RecoverySuccessful = result
  └─► If Not recovery successful:
         Increment threshold
         If source is critical: escalate to HandleFatalError
  └─► Broadcast OnRecoveryAttempted(Error.ErrorID, result)

[HandleFatalError]
  └─► If bAutosaveOnError: SS_SaveManager.QuickSave()
  └─► ShowErrorScreen(Error):
         Create WBP_ErrorScreen
         Display error code, message
         Show recovery options (Retry, Load Last Save, Quit)
  └─► Set timer for auto-quit (10 seconds if no input)

[LogError]
  └─► ErrorLog.Add(Error)
  └─► If ErrorLog.Length > MaxLogSize: Remove oldest entry
  └─► Write to BPC_LogManager:
         Error.Severity: Error log level
         Message: TechnicalDetails
  └─► If bLogErrorsToFile: Append to Saved/Errors/ErrorLog.txt

[ShowErrorScreen]
  └─► If bShowingErrorScreen: return (already displayed)
  └─► bShowingErrorScreen = true
  └─► Pause game
  └─► Create WBP_ErrorScreen
  └─► Set error code (ErrorID), description (Message)
  └─► Show recovery buttons:
         If recovery available: Retry button
         If critical: Load Last Save, Quit buttons
  └─► Add to viewport

[DismissErrorScreen]
  └─► If Not bShowingErrorScreen: return
  └─► bShowingErrorScreen = false
  └─► Remove WBP_ErrorScreen from viewport
  └─► Resume game (unless transitioning to menu)
```

### Event Dispatchers

| Name | Payload | Description |
|------|---------|-------------|
| `OnErrorOccurred` | Error: FErrorEntry | Any error trapped |
| `OnRecoveryAttempted` | ErrorID: FName, bSuccess: Bool | Recovery result |
| `OnFatalError` | Error: FErrorEntry | Unrecoverable error |

### Communications With

| Target | Method | Why |
|--------|--------|-----|
| [`SS_SaveManager`](../05-saveload/28_SS_SaveManager.md) | Direct call | Autosave on critical |
| [`BPC_LoadingScreen`](../11-polish/76_BPC_LoadingScreen.md) | Direct call | Error transition |
| [`BPC_AnalyticsTracker`](../11-polish/82_BPC_AnalyticsTracker.md) | Direct call | Error telemetry |
| [`WBP_ErrorScreen`](../06-ui/49_WBP_ErrorScreen.md) | Create widget | Error UI |
| [`BPC_LogManager`](../01-core/06_BPC_LogManager.md) | Direct call | Logging |

### Reuse Notes
- Severity-based escalation prevents minor issues from interrupting gameplay
- Retry thresholds with cooldown prevent infinite retry loops
- Recovery handlers are registered per system; extensible architecture
- Error screen gives player clear options instead of silent crash
- Autosave on critical error protects player progress
- Error log persists session errors for developer debugging
- Health check system enables proactive error prevention
- All error messages user-friendly; technical details separate for logs