edge_impulse_runner/
error.rs

1//! Error types for the Edge Impulse Runner.
2//!
3//! This module defines the error types that can occur during model loading,
4//! execution, and communication. It provides a comprehensive error handling
5//! system that helps identify and debug issues when working with Edge Impulse
6//! models.
7//!
8//! The main error type is `EimError`, which encompasses all possible error
9//! conditions that can occur within the library.
10
11use std::error::Error;
12use std::fmt;
13use std::io;
14use thiserror::Error;
15
16/// Represents all possible errors that can occur in the Edge Impulse Runner.
17///
18/// This enum implements the standard Error trait using thiserror and provides
19/// detailed error messages for each error case. It handles both internal errors
20/// and wrapped errors from external dependencies.
21#[derive(Error, Debug)]
22pub enum EimError {
23    /// Indicates a failure in file system operations when accessing the EIM file.
24    ///
25    /// This error occurs when there are problems reading, writing, or accessing
26    /// the model file. It wraps the standard IO error for more details.
27    #[error("Failed to access EIM file: {0}")]
28    FileError(#[from] std::io::Error),
29
30    /// Indicates that the provided path to the EIM file is invalid.
31    ///
32    /// This error occurs when:
33    /// - The path doesn't exist
34    /// - The file extension is not .eim
35    /// - The path points to a directory instead of a file
36    #[error("Invalid EIM file path")]
37    InvalidPath,
38
39    /// Indicates a failure during model execution.
40    ///
41    /// This error occurs when:
42    /// - The model process crashes
43    /// - The model fails to initialize
44    /// - There's an internal model error during inference
45    #[error("Failed to execute EIM model: {0}")]
46    ExecutionError(String),
47
48    /// Indicates a failure in Unix socket communication.
49    ///
50    /// This error occurs when:
51    /// - The socket connection fails
52    /// - Messages can't be sent or received
53    /// - The socket connection is unexpectedly closed
54    #[error("Socket communication error: {0}")]
55    SocketError(String),
56
57    /// Indicates a failure in JSON serialization or deserialization.
58    ///
59    /// This error occurs when:
60    /// - Messages can't be encoded to JSON
61    /// - Responses can't be decoded from JSON
62    /// - The JSON structure doesn't match expected schema
63    #[error("JSON error: {0}")]
64    JsonError(#[from] serde_json::Error),
65
66    /// Indicates that the provided input data is invalid.
67    ///
68    /// This error occurs when:
69    /// - Input features don't match expected dimensions
70    /// - Input values are out of valid ranges
71    /// - Required input parameters are missing
72    #[error("Invalid input: {0}")]
73    InvalidInput(String),
74
75    /// Indicates that an invalid operation was attempted.
76    ///
77    /// This error occurs when:
78    /// - Operations are called in wrong order
79    /// - Unsupported operations are requested
80    /// - Operation parameters are incompatible
81    #[error("Invalid operation: {0}")]
82    InvalidOperation(String),
83}
84
85#[derive(Debug)]
86pub enum IngestionError {
87    Server { status_code: u16, message: String },
88    Config(String),
89    Network(reqwest::Error),
90    Json(serde_json::Error),
91    Header(reqwest::header::InvalidHeaderValue),
92    Io(io::Error),
93}
94
95impl fmt::Display for IngestionError {
96    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97        match self {
98            IngestionError::Server {
99                status_code,
100                message,
101            } => {
102                write!(f, "Server error {}: {}", status_code, message)
103            }
104            IngestionError::Config(msg) => write!(f, "Configuration error: {}", msg),
105            IngestionError::Network(e) => write!(f, "Network error: {}", e),
106            IngestionError::Json(e) => write!(f, "JSON error: {}", e),
107            IngestionError::Header(e) => write!(f, "Header error: {}", e),
108            IngestionError::Io(e) => write!(f, "IO error: {}", e),
109        }
110    }
111}
112
113impl Error for IngestionError {
114    fn source(&self) -> Option<&(dyn Error + 'static)> {
115        match self {
116            IngestionError::Network(e) => Some(e),
117            IngestionError::Json(e) => Some(e),
118            IngestionError::Header(e) => Some(e),
119            IngestionError::Io(e) => Some(e),
120            _ => None,
121        }
122    }
123}
124
125impl From<reqwest::Error> for IngestionError {
126    fn from(err: reqwest::Error) -> Self {
127        IngestionError::Network(err)
128    }
129}
130
131impl From<serde_json::Error> for IngestionError {
132    fn from(err: serde_json::Error) -> Self {
133        IngestionError::Json(err)
134    }
135}
136
137impl From<reqwest::header::InvalidHeaderValue> for IngestionError {
138    fn from(err: reqwest::header::InvalidHeaderValue) -> Self {
139        IngestionError::Header(err)
140    }
141}
142
143impl From<io::Error> for IngestionError {
144    fn from(err: io::Error) -> Self {
145        IngestionError::Io(err)
146    }
147}