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}