Skip to main content

restart_manager/
error.rs

1//! Stable error classification without exposing implementation details.
2
3/// Specialised result alias used by this crate.
4pub type Result<T> = std::result::Result<T, Error>;
5
6/// A stable, non-exhaustive classification of failures.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8#[non_exhaustive]
9pub enum ErrorKind {
10    /// The requested operating-system operation is unavailable on this target.
11    UnsupportedPlatform,
12    /// All 64 Restart Manager session slots in the user session are occupied.
13    SessionLimit,
14    /// A session key was malformed, expired, or otherwise rejected.
15    InvalidSessionKey,
16    /// A shutdown or restart operation was cancelled.
17    Cancelled,
18    /// Windows denied access to a resource or process.
19    AccessDenied,
20    /// Input could not be represented by the native API.
21    InvalidInput,
22    /// Restart Manager does not accept directories as file resources.
23    DirectoryNotSupported,
24    /// A collection was too large for the native `u32` count fields.
25    TooManyResources,
26    /// Another process-wide progress callback operation is active.
27    CallbackInUse,
28    /// The affected-application or filter list changed through every retry.
29    DataChanged,
30    /// Windows returned an internally inconsistent buffer.
31    MalformedOsData,
32    /// Windows requires a system reboot before this operation can proceed.
33    RebootRequired,
34    /// At least one affected application could not be shut down.
35    ShutdownIncomplete,
36    /// At least one stopped application could not be restarted.
37    RestartIncomplete,
38    /// An operation was requested in an invalid native sequence.
39    OperationOutOfSequence,
40    /// Restart Manager could not access its registry state.
41    RegistryUnavailable,
42    /// The selected filter does not exist.
43    FilterNotFound,
44    /// The operating system could not allocate required memory.
45    OutOfMemory,
46    /// This process already owns a crate-managed restart registration.
47    ApplicationRestartInUse,
48    /// A dedicated asynchronous worker thread could not be created or failed.
49    AsyncWorkerUnavailable,
50    /// The weak cancellation capability refers to an ended session.
51    SessionEnded,
52    /// Another Windows error not covered by a more specific classification.
53    Os,
54}
55
56/// An error returned by the safe Restart Manager API.
57///
58/// Its representation is private. Match on [`Error::kind`] and use
59/// [`Error::raw_os_error`] when the precise Win32 value matters.
60#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
61#[error("{message}")]
62pub struct Error {
63    kind: ErrorKind,
64    raw_os_error: Option<u32>,
65    raw_hresult: Option<i32>,
66    message: String,
67}
68
69impl Error {
70    /// Returns the stable classification for this error.
71    #[must_use]
72    pub const fn kind(&self) -> ErrorKind {
73        self.kind
74    }
75
76    /// Returns the original Win32 error code, when the failure came from Windows.
77    #[must_use]
78    pub const fn raw_os_error(&self) -> Option<u32> {
79        self.raw_os_error
80    }
81
82    /// Returns the original HRESULT for application-restart failures.
83    #[must_use]
84    pub const fn raw_hresult(&self) -> Option<i32> {
85        self.raw_hresult
86    }
87
88    pub(crate) fn new(
89        kind: ErrorKind,
90        raw_os_error: Option<u32>,
91        message: impl Into<String>,
92    ) -> Self {
93        Self {
94            kind,
95            raw_os_error,
96            raw_hresult: None,
97            message: message.into(),
98        }
99    }
100
101    pub(crate) fn from_hresult(kind: ErrorKind, hresult: i32, message: impl Into<String>) -> Self {
102        Self {
103            kind,
104            raw_os_error: None,
105            raw_hresult: Some(hresult),
106            message: message.into(),
107        }
108    }
109}
110
111/// Error returned when parsing a Restart Manager session key.
112#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)]
113#[error("a session key must contain exactly 32 ASCII hexadecimal characters")]
114pub struct ParseSessionKeyError;