instro_ethernetip/
error.rs1use std::error::Error as StdError;
2
3use rust_ethernet_ip::BatchError;
4use thiserror::Error;
5
6#[derive(Debug, Clone, Error)]
12pub enum BatchReadError {
13 #[error("tag not found: {0}")]
14 TagNotFound(String),
15 #[error("data type mismatch: expected {expected}, got {actual}")]
16 DataTypeMismatch { expected: String, actual: String },
17 #[error("network error: {0}")]
18 Network(String),
19 #[error("CIP error (0x{status:02X}): {message}")]
20 Cip { status: u8, message: String },
21 #[error("tag path error: {0}")]
22 TagPath(String),
23 #[error("serialization error: {0}")]
24 Serialization(String),
25 #[error("operation timeout")]
26 Timeout,
27 #[error("error: {0}")]
28 Other(String),
29}
30
31impl From<BatchError> for BatchReadError {
32 fn from(value: BatchError) -> Self {
33 match value {
34 BatchError::TagNotFound(tag) => Self::TagNotFound(tag),
35 BatchError::DataTypeMismatch { expected, actual } => {
36 Self::DataTypeMismatch { expected, actual }
37 }
38 BatchError::NetworkError(msg) => Self::Network(msg),
39 BatchError::CipError { status, message } => Self::Cip { status, message },
40 BatchError::TagPathError(msg) => Self::TagPath(msg),
41 BatchError::SerializationError(msg) => Self::Serialization(msg),
42 BatchError::Timeout => Self::Timeout,
43 BatchError::Other(msg) => Self::Other(msg),
44 }
45 }
46}
47
48impl BatchReadError {
49 pub(crate) fn is_retriable(&self) -> bool {
50 matches!(self, Self::Network(_) | Self::Timeout)
51 }
52}
53
54#[derive(Debug, Error)]
56pub enum Error {
57 #[cfg(feature = "blocking")]
58 #[error("failed to create Tokio runtime for blocking EtherNet/IP session: {source}")]
59 CreateRuntime {
60 #[source]
61 source: Box<dyn StdError + Send + Sync>,
62 },
63 #[error("failed to connect to EtherNet/IP device at {addr}: {source}")]
64 Connect {
65 addr: String,
66 #[source]
68 source: Box<dyn StdError + Send + Sync>,
69 },
70 #[error("failed to read tag '{tag_name}' from {addr}: {source}")]
71 ReadTag {
72 addr: String,
73 tag_name: String,
74 #[source]
75 source: Box<dyn StdError + Send + Sync>,
76 },
77 #[error("failed to read batch of tags from {addr}: {source}")]
78 BatchRead {
79 addr: String,
80 #[source]
81 source: Box<dyn StdError + Send + Sync>,
82 },
83 #[error("failed to read tag '{tag_name}' from {addr}: {source}")]
84 BatchReadItem {
85 addr: String,
86 tag_name: String,
87 #[source]
88 source: BatchReadError,
89 },
90 #[error("failed to decode structured tag '{tag_name}' from {addr} as {target_type}: {source}")]
91 DecodeStructuredTag {
92 addr: String,
93 tag_name: String,
94 target_type: &'static str,
95 #[source]
96 source: Box<dyn StdError + Send + Sync>,
97 },
98 #[error(
99 "failed to decode structured tag '{tag_name}' from {addr}: expected structured value, got {actual_type}"
100 )]
101 UnexpectedValueType {
102 addr: String,
103 tag_name: String,
104 actual_type: &'static str,
105 },
106 #[error("failed to write tag '{tag_name}' on {addr}: {source}")]
107 WriteTag {
108 addr: String,
109 tag_name: String,
110 #[source]
111 source: Box<dyn StdError + Send + Sync>,
112 },
113 #[error("failed to unregister explicit EtherNet/IP session for {addr}: {source}")]
114 Unregister {
115 addr: String,
116 #[source]
117 source: Box<dyn StdError + Send + Sync>,
118 },
119}