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