| 1 | //! Error types for WANDA |
| 2 | |
| 3 | use std::path::PathBuf; |
| 4 | use thiserror::Error; |
| 5 | |
| 6 | /// Result type alias using WandaError |
| 7 | pub type Result<T> = std::result::Result<T, WandaError>; |
| 8 | |
| 9 | /// Main error type for WANDA operations |
| 10 | #[derive(Error, Debug)] |
| 11 | pub enum WandaError { |
| 12 | // Steam errors |
| 13 | #[error("Steam installation not found")] |
| 14 | SteamNotFound, |
| 15 | |
| 16 | #[error("Steam library at {path} is inaccessible: {reason}")] |
| 17 | SteamLibraryInaccessible { path: PathBuf, reason: String }, |
| 18 | |
| 19 | #[error("Failed to parse VDF file {path}: {reason}")] |
| 20 | VdfParseError { path: PathBuf, reason: String }, |
| 21 | |
| 22 | #[error("Game with app ID {app_id} not found")] |
| 23 | GameNotFound { app_id: u32 }, |
| 24 | |
| 25 | // Proton errors |
| 26 | #[error("No compatible Proton version found")] |
| 27 | ProtonNotFound, |
| 28 | |
| 29 | #[error("Proton version {version} is incompatible: {reason}")] |
| 30 | ProtonIncompatible { version: String, reason: String }, |
| 31 | |
| 32 | // Prefix errors |
| 33 | #[error("Prefix at {path} is corrupted: {reason}")] |
| 34 | PrefixCorrupted { path: PathBuf, reason: String }, |
| 35 | |
| 36 | #[error("Failed to create prefix at {path}: {reason}")] |
| 37 | PrefixCreationFailed { path: PathBuf, reason: String }, |
| 38 | |
| 39 | #[error("Prefix at {path} not found")] |
| 40 | PrefixNotFound { path: PathBuf }, |
| 41 | |
| 42 | #[error("Winetricks failed: {reason}")] |
| 43 | WinetricksFailed { reason: String }, |
| 44 | |
| 45 | // WeMod errors |
| 46 | #[error("Failed to download WeMod: {reason}")] |
| 47 | WemodDownloadFailed { reason: String }, |
| 48 | |
| 49 | #[error("WeMod installation failed: {reason}")] |
| 50 | WemodInstallFailed { reason: String }, |
| 51 | |
| 52 | #[error("WeMod not installed")] |
| 53 | WemodNotInstalled, |
| 54 | |
| 55 | // Launch errors |
| 56 | #[error("Failed to launch game: {reason}")] |
| 57 | LaunchFailed { reason: String }, |
| 58 | |
| 59 | #[error("Process terminated unexpectedly: {reason}")] |
| 60 | ProcessCrashed { reason: String }, |
| 61 | |
| 62 | // Configuration errors |
| 63 | #[error("Configuration error: {reason}")] |
| 64 | ConfigError { reason: String }, |
| 65 | |
| 66 | #[error("Configuration file not found at {path}")] |
| 67 | ConfigNotFound { path: PathBuf }, |
| 68 | |
| 69 | // Generic errors |
| 70 | #[error("IO error: {0}")] |
| 71 | Io(#[from] std::io::Error), |
| 72 | |
| 73 | #[error("HTTP error: {0}")] |
| 74 | Http(#[from] reqwest::Error), |
| 75 | |
| 76 | #[error("JSON error: {0}")] |
| 77 | Json(#[from] serde_json::Error), |
| 78 | |
| 79 | #[error("TOML parse error: {0}")] |
| 80 | TomlParse(#[from] toml::de::Error), |
| 81 | |
| 82 | #[error("TOML serialize error: {0}")] |
| 83 | TomlSerialize(#[from] toml::ser::Error), |
| 84 | } |
| 85 | |
| 86 | impl WandaError { |
| 87 | /// Get a user-friendly message with suggestions |
| 88 | pub fn user_message(&self) -> String { |
| 89 | match self { |
| 90 | Self::SteamNotFound => { |
| 91 | "Steam installation not found. Please ensure Steam is installed, \ |
| 92 | or specify the path manually in the config." |
| 93 | .into() |
| 94 | } |
| 95 | Self::ProtonNotFound => { |
| 96 | "No compatible Proton version found. Please install GE-Proton \ |
| 97 | or Proton Experimental from Steam." |
| 98 | .into() |
| 99 | } |
| 100 | Self::PrefixCorrupted { path, reason } => { |
| 101 | format!( |
| 102 | "The Wine prefix at {} appears to be corrupted: {}\n\ |
| 103 | Try running 'wanda prefix repair' to fix this issue.", |
| 104 | path.display(), |
| 105 | reason |
| 106 | ) |
| 107 | } |
| 108 | Self::WemodNotInstalled => { |
| 109 | "WeMod is not installed. Run 'wanda init' to set up WANDA.".into() |
| 110 | } |
| 111 | _ => self.to_string(), |
| 112 | } |
| 113 | } |
| 114 | } |
| 115 |