wsl_api/
error.rs

1use windows::core::HRESULT;
2
3#[derive(Debug)]
4enum UnderlyingError {
5    Lxss(wsl_com_api_sys::LxssError),
6    Windows(windows::core::Error),
7}
8
9#[derive(Debug)]
10pub struct WslError {
11    underlying: UnderlyingError,
12}
13
14#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
15pub enum WslErrorKind {
16    UnsupportedOperatingSystem,
17    UnsupportedWslVersion,
18}
19
20impl WslError {
21    pub fn hresult(&self) -> HRESULT {
22        match &self.underlying {
23            UnderlyingError::Lxss(e) => e.0,
24            UnderlyingError::Windows(e) => e.code(),
25        }
26    }
27
28    pub fn kind(&self) -> Option<WslErrorKind> {
29        #[cfg(not(windows))]
30        return Some(WslErrorKind::UnsupportedOperatingSystem);
31
32        #[cfg(windows)]
33        match self.hresult() {
34            windows::Win32::Foundation::REGDB_E_CLASSNOTREG => {
35                Some(WslErrorKind::UnsupportedWslVersion)
36            }
37            _ => None,
38        }
39    }
40}
41
42impl std::fmt::Display for WslError {
43    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44        let known_error = known_error(self.hresult());
45        if known_error.is_empty() {
46            write!(
47                f,
48                "Unknown WSL error 0x{:08x}: {}",
49                self.hresult().0,
50                self.hresult().message()
51            )
52        } else {
53            write!(f, "WSL error: {}", known_error)
54        }
55    }
56}
57
58impl std::error::Error for WslError {
59    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
60        match &self.underlying {
61            UnderlyingError::Lxss(_) => None,
62            UnderlyingError::Windows(e) => Some(e),
63        }
64    }
65}
66
67impl From<wsl_com_api_sys::LxssError> for WslError {
68    fn from(value: wsl_com_api_sys::LxssError) -> Self {
69        WslError {
70            underlying: UnderlyingError::Lxss(value),
71        }
72    }
73}
74
75impl From<windows::core::Error> for WslError {
76    fn from(value: windows::core::Error) -> Self {
77        WslError {
78            underlying: UnderlyingError::Windows(value),
79        }
80    }
81}
82
83fn known_error(error: HRESULT) -> &'static str {
84    use wsl_com_api_sys::error::*;
85    match error {
86        WSL_E_DEFAULT_DISTRO_NOT_FOUND => "Default distribution not found",
87        WSL_E_DISTRO_NOT_FOUND => "Distribution not found",
88        WSL_E_WSL1_NOT_SUPPORTED => "WSL 1 not supported",
89        WSL_E_VM_MODE_NOT_SUPPORTED => "VM mode not supported",
90        WSL_E_TOO_MANY_DISKS_ATTACHED => "Too many disks attached",
91        WSL_E_CONSOLE => "Console",
92        WSL_E_CUSTOM_KERNEL_NOT_FOUND => "Custom kernel not found",
93        WSL_E_USER_NOT_FOUND => "User not found",
94        WSL_E_INVALID_USAGE => "Invalid usage",
95        WSL_E_EXPORT_FAILED => "Export failed",
96        WSL_E_IMPORT_FAILED => "Import failed",
97        WSL_E_DISTRO_NOT_STOPPED => "Distribution not stopped",
98        WSL_E_TTY_LIMIT => "TTY limit",
99        WSL_E_CUSTOM_SYSTEM_DISTRO_ERROR => "Custom system distro error",
100        WSL_E_LOWER_INTEGRITY => "Lower integrity",
101        WSL_E_HIGHER_INTEGRITY => "Higher integrity",
102        WSL_E_FS_UPGRADE_NEEDED => "FS upgrade needed",
103        WSL_E_USER_VHD_ALREADY_ATTACHED => "User VHD already attached",
104        WSL_E_VM_MODE_INVALID_STATE => "VM mode invalid state",
105        WSL_E_VM_MODE_MOUNT_NAME_ALREADY_EXISTS => "VM mode mount name already exists",
106        WSL_E_ELEVATION_NEEDED_TO_MOUNT_DISK => "Elevation needed to mount disk",
107        WSL_E_DISK_ALREADY_ATTACHED => "Disk already attached",
108        WSL_E_DISK_ALREADY_MOUNTED => "Disk already mounted",
109        WSL_E_DISK_MOUNT_FAILED => "Disk mount failed",
110        WSL_E_DISK_UNMOUNT_FAILED => "Disk unmount failed",
111        WSL_E_WSL2_NEEDED => "WSL 2 needed",
112        WSL_E_VM_MODE_INVALID_MOUNT_NAME => "VM mode invalid mount name",
113        WSL_E_GUI_APPLICATIONS_DISABLED => "GUI applications disabled",
114        WSL_E_DISTRO_ONLY_AVAILABLE_FROM_STORE => "Distribution only available from store",
115        WSL_E_WSL_MOUNT_NOT_SUPPORTED => "WSL mount not supported",
116        WSL_E_WSL_OPTIONAL_COMPONENT_REQUIRED => "WSL optional component required",
117        WSL_E_VMSWITCH_NOT_FOUND => "VMSwitch not found",
118        WSL_E_VMSWITCH_NOT_SET => "VMSwitch not set",
119        WSL_E_NOT_A_LINUX_DISTRO => "Not a Linux distro",
120        WSL_E_OS_NOT_SUPPORTED => "OS not supported",
121        WSL_E_INSTALL_PROCESS_FAILED => "Install process failed",
122        WSL_E_INSTALL_COMPONENT_FAILED => "Install component failed",
123        WSL_E_DISK_MOUNT_DISABLED => "Disk mount disabled",
124        WSL_E_WSL1_DISABLED => "WSL 1 disabled",
125        WSL_E_VIRTUAL_MACHINE_PLATFORM_REQUIRED => "Virtual machine platform required",
126        WSL_E_LOCAL_SYSTEM_NOT_SUPPORTED => "Local system not supported",
127        WSL_E_DISK_CORRUPTED => "Disk corrupted",
128        WSL_E_DISTRIBUTION_NAME_NEEDED => "Distribution name needed",
129        WSL_E_INVALID_JSON => "Invalid JSON",
130        WSL_E_VM_CRASHED => "VM crashed",
131        _ => "",
132    }
133}