furiosa_device/
error.rs

1use std::convert::Infallible;
2use std::fmt::Display;
3use std::io;
4
5use thiserror::Error;
6
7use crate::hwmon::error::HwmonError;
8use crate::perf_regs::error::PerformanceCounterError;
9use crate::DeviceError::{IncompatibleDriver, UnexpectedValue};
10
11/// Type alias for `Result<T, DeviceError>`.
12pub type DeviceResult<T> = Result<T, DeviceError>;
13
14/// An error that occurred during parsing or retrieving devices.
15#[derive(Debug, Error)]
16pub enum DeviceError {
17    #[error("Device {name} not found")]
18    DeviceNotFound { name: String },
19    #[error("Device {name} found but still in use")]
20    DeviceBusy { name: String },
21    #[error("IoError: {cause}")]
22    IoError { cause: io::Error },
23    #[error("PermissionDenied: {cause}")]
24    PermissionDenied { cause: io::Error },
25    #[error("Unknown architecture, arch: {arch}, rev: {rev}")]
26    UnknownArch { arch: String, rev: String },
27    #[error("Incompatible device driver: {cause}")]
28    IncompatibleDriver { cause: String },
29    #[error("HwmonError: [npu{device_index}] {cause}")]
30    HwmonError { device_index: u8, cause: HwmonError },
31    #[error("PerformanceCounterError: {cause}")]
32    PerformanceCounterError { cause: PerformanceCounterError },
33    #[error("Unexpected value: {message}")]
34    UnexpectedValue { message: String },
35    #[error("Failed to parse given message {message}: {cause}")]
36    ParseError { message: String, cause: String },
37}
38
39impl DeviceError {
40    pub(crate) fn device_not_found<D: Display>(name: D) -> DeviceError {
41        DeviceError::DeviceNotFound {
42            name: name.to_string(),
43        }
44    }
45
46    pub(crate) fn device_busy<D: Display>(name: D) -> DeviceError {
47        DeviceError::DeviceBusy {
48            name: name.to_string(),
49        }
50    }
51
52    pub(crate) fn unrecognized_file<F: Display>(file: F) -> DeviceError {
53        IncompatibleDriver {
54            cause: format!("{file} file cannot be recognized"),
55        }
56    }
57
58    pub(crate) fn invalid_device_file<F: Display>(file: F) -> DeviceError {
59        IncompatibleDriver {
60            cause: format!("{file} is not a valid device file"),
61        }
62    }
63
64    pub(crate) fn hwmon_error(device_index: u8, cause: HwmonError) -> DeviceError {
65        DeviceError::HwmonError {
66            device_index,
67            cause,
68        }
69    }
70
71    pub(crate) fn performance_counter_error(cause: PerformanceCounterError) -> DeviceError {
72        DeviceError::PerformanceCounterError { cause }
73    }
74
75    pub(crate) fn unexpected_value<S: ToString>(message: S) -> DeviceError {
76        UnexpectedValue {
77            message: message.to_string(),
78        }
79    }
80
81    pub(crate) fn parse_error<S: ToString, C: ToString>(message: S, cause: C) -> DeviceError {
82        DeviceError::ParseError {
83            message: message.to_string(),
84            cause: cause.to_string(),
85        }
86    }
87}
88
89impl From<io::Error> for DeviceError {
90    fn from(e: io::Error) -> Self {
91        if e.kind() == std::io::ErrorKind::PermissionDenied {
92            Self::PermissionDenied { cause: e }
93        } else {
94            Self::IoError { cause: e }
95        }
96    }
97}
98
99impl From<Infallible> for DeviceError {
100    fn from(_: Infallible) -> Self {
101        unreachable!()
102    }
103}