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}