netpulse/errors.rs
1//! Error types for the netpulse crate.
2//!
3//! This module provides specialized error types for different components of netpulse:
4//! - [`StoreError`] - Errors related to store operations (loading, saving, versioning)
5//! - [`CheckError`] - Errors that occur during network checks (HTTP, ICMP)
6//! - [`RunError`] - Errors specific to executable operations
7//! - [`AnalysisError`] - Errors that occur during analysis and report generation
8//!
9//! All error types implement the standard Error trait and provide detailed error information.
10//!
11//! # Examples
12//!
13//! ```rust,no_run
14//! use netpulse::store::Store;
15//! use netpulse::errors::StoreError;
16//!
17//! fn load_store() -> Result<Store, StoreError> {
18//! match Store::load(false) {
19//! Ok(store) => Ok(store),
20//! Err(StoreError::DoesNotExist) => Store::create(),
21//! Err(e) => Err(e),
22//! }
23//! }
24//! ```
25
26use flagset::FlagSet;
27use thiserror::Error;
28
29use crate::records::CheckFlag;
30
31/// Errors that can occur during store operations.
32///
33/// These errors handle various failure modes when interacting with the store:
34/// - File system operations
35/// - Data serialization/deserialization
36/// - Version compatibility
37#[derive(Error, Debug)]
38pub enum StoreError {
39 /// The store file does not exist.
40 ///
41 /// This typically occurs on first run or if the store file was deleted.
42 #[error("The store does not exist")]
43 DoesNotExist,
44 /// An I/O error occurred during store operations.
45 ///
46 /// This can happen during file reading, writing, or filesystem operations.
47 #[error("IO Error: {source}")]
48 Io {
49 /// Underlying error
50 #[from]
51 source: std::io::Error,
52 },
53 /// Failed to load store data from file.
54 ///
55 /// This typically indicates corruption or an incompatible / outdated store format.
56 #[error("Could not deserialize the store from the loaded data: {source}")]
57 Load {
58 /// Underlying error
59 #[from]
60 source: bincode::Error,
61 },
62 /// Failed to convert data to UTF-8.
63 ///
64 /// This can occur when reading store metadata like file hashes.
65 #[error("Could not convert data to Utf8")]
66 Str {
67 /// Underlying error
68 #[from]
69 source: std::str::Utf8Error,
70 },
71 /// A subprocess (like sha256sum) exited with non-zero status.
72 #[error("A subprocess ended non successfully")]
73 ProcessEndedWithoutSuccess,
74 /// Attempted to load a store with an unsupported version number.
75 ///
76 /// This occurs when the store file version is newer or older than what this version
77 /// of netpulse supports.
78 #[error("Tried to load a store with an unsupported version")]
79 UnsupportedVersion,
80 /// A [Check](crate::records::Check) has flags that are exclusive to each other.
81 ///
82 /// This variant contains a [FlagSet] with only the conflicting [CheckFlags](CheckFlag) set.
83 #[error("Check has ambiguous flags: {0:?}")]
84 AmbiguousFlags(FlagSet<CheckFlag>),
85 /// A [Check](crate::records::Check) that does not have the required flags to be valid.
86 ///
87 /// This variant contains a [FlagSet] with only the flags [CheckFlags](CheckFlag) set that
88 /// would make it a valid state. Exactly one of these flags must be set.
89 #[error("Check is missing at least one of these flags: {0:?}")]
90 MissingFlag(FlagSet<CheckFlag>),
91 /// Occurs when trying to convert an arbitrary [u8] to a [Version](crate::store::Version) that
92 /// is not defined. Only known [Versions][crate::store::Version] are valid.
93 #[error("Tried to load a store version that does not exist: {0}")]
94 BadStoreVersion(u8),
95 /// A store can be loaded as readonly if it's corrupted or there is a version mismatch
96 #[error("Tried to save a readonly store")]
97 IsReadonly,
98}
99
100/// Errors that can occur during network checks.
101///
102/// These errors handle failures during the actual network connectivity tests,
103/// whether HTTP, ICMP, or other protocols.
104#[derive(Error, Debug)]
105pub enum CheckError {
106 /// An I/O error occurred during the check.
107 ///
108 /// This typically indicates network-level failures.
109 #[error("IO Error {source}")]
110 Io {
111 /// Underlying error
112 #[from]
113 source: std::io::Error,
114 },
115 /// An error occurred during ICMP ping.
116 ///
117 /// This variant is only available when the `ping` feature is enabled.
118 #[cfg(feature = "ping")]
119 #[error("Ping Error: {source}")]
120 Ping {
121 /// Underlying error
122 #[from]
123 source: ping::Error,
124 },
125 /// An error occurred during HTTP check.
126 ///
127 /// This variant is only available when the `http` feature is enabled.
128 #[cfg(feature = "http")]
129 #[error("Http Error: {source}")]
130 Http {
131 /// Underlying error
132 #[from]
133 source: curl::Error,
134 },
135}
136
137/// Errors that can occur during daemon operations.
138///
139/// These errors handle failures in the daemon process, including store
140/// operations and process management.
141#[derive(Error, Debug)]
142pub enum RunError {
143 /// An error occurred while operating on the store.
144 #[error("Something went wrong with the store: {source}")]
145 StoreError {
146 /// Underlying error
147 #[from]
148 source: StoreError,
149 },
150 /// An I/O error occurred during daemon operations.
151 #[error("IO Error: {source}")]
152 Io {
153 /// Underlying error
154 #[from]
155 source: std::io::Error,
156 },
157 /// Failed to format analysis output.
158 #[error("Text Formatting error: {source}")]
159 Fmt {
160 /// Underlying error
161 #[from]
162 source: std::fmt::Error,
163 },
164}
165
166/// Errors that can occur during analysis and report generation.
167///
168/// These errors handle failures when analyzing check results and
169/// generating human-readable reports.
170#[derive(Error, Debug)]
171pub enum AnalysisError {
172 /// An error occurred while accessing the store.
173 #[error("Something went wrong with the store: {source}")]
174 StoreError {
175 /// Underlying error
176 #[from]
177 source: StoreError,
178 },
179 /// Failed to format analysis output.
180 #[error("Text Formatting error: {source}")]
181 Fmt {
182 /// Underlying error
183 #[from]
184 source: std::fmt::Error,
185 },
186 /// An I/O error occurred during analysis operations.
187 #[error("IO Error: {source}")]
188 Io {
189 /// Underlying error
190 #[from]
191 source: std::io::Error,
192 },
193}