# Fallback Pattern Guide The Fallback pattern provides alternative results when operations fail, enabling graceful degradation. ## When to Use - You have cached data as an alternative - You can return default values - You can provide degraded functionality - You want to ensure operations always return a result ## When NOT to Use - Failures should propagate (no reasonable fallback) - Operations must succeed or fail (no middle ground) - Fallback is as expensive as the primary operation ## Quick Start ```pascal uses Murphy.Policy.Fallback; var Policy: IFallbackPolicy; Data: string; begin Policy := TFallbackBuilder .Handle(Exception) .Fallback(function: string begin Result := 'Default Value'; end) .Build; Data := Policy.Execute(function: string begin Result := FetchData; end); end; ``` ## Common Scenarios ### Cached Data Fallback ```pascal type TDataService = class private FCache: string; public function GetData: string; end; function TDataService.GetData: string; var Policy: IFallbackPolicy; begin Policy := TFallbackBuilder .Handle(Exception) .Fallback(function: string begin WriteLn('Using cached data'); Result := FCache; end) .Build; Result := Policy.Execute( function: string begin var Fresh := FetchFromAPI; FCache := Fresh; // Update cache Result := Fresh; end); end; ``` ### Default Values ```pascal function GetUserPreference(Key: string): string; var Policy: IFallbackPolicy; begin Policy := TFallbackBuilder .Handle(Exception) .Fallback(function: string begin Result := 'default'; end) .Build; Result := Policy.Execute( function: string begin Result := Database.Query('SELECT value FROM prefs WHERE key = ?', [Key]); end); end; ``` ### Fallback Chain ```pascal function GetConfig: string; var DatabasePolicy, FilePolicy: IFallbackPolicy; begin // Try database, fall back to file DatabasePolicy := TFallbackBuilder .Handle(EDatabaseError) .Fallback(function: string begin Result := ReadConfigFile; end) .Build; // Try API, fall back to database/file FilePolicy := TFallbackBuilder .Handle(Exception) .Fallback(function: string begin Result := DatabasePolicy.Execute( function: string begin Result := GetFromDatabase; end); end) .Build; Result := FilePolicy.Execute(function: string begin Result := GetFromAPI; end); end; ``` ## Best Practices 1. **Fallback should be reliable** - Don't let fallback throw exceptions 2. **Indicate degraded mode** - Log when fallback is used 3. **Consider staleness** - Cached data may be outdated 4. **Memory management** - Be careful with object-based fallbacks 5. **Test fallback paths** - Ensure they work correctly ## See Also - [Fallback API Reference](../API-Reference/Fallback-Policy.md) - [Combining Patterns](Combining-Patterns.md) --- [Back to Index](../Home.md)