1use std::env::VarError;
2use std::net::AddrParseError;
3
4use snafu::Snafu;
5
6use crate::DataLenType;
7use crate::checksum::ChecksumType;
8
9#[derive(Debug, Snafu)]
10#[snafu(visibility(pub))]
13pub enum Error {
14 #[snafu(display("read `checksum` from network error"))]
16 MsgNetworkReadCheckSum { source: std::io::Error },
17 #[snafu(display("read `datalen` from network error"))]
18 MsgNetworkReadDatalen { source: std::io::Error },
19 #[snafu(display("read `buffered_raw_data` from network error"))]
20 MsgNetworkReadBufferdRawData { source: std::io::Error },
21 #[snafu(display("read `msg_body` from network error"))]
22 MsgNetworkReadBody { source: std::io::Error },
23 #[snafu(display("write `checksum` to network error"))]
24 MsgNetworkWriteCheckSum { source: std::io::Error },
25 #[snafu(display("write `datalen` to network error"))]
26 MsgNetworkWriteDatalen { source: std::io::Error },
27 #[snafu(display("write `msg_body` to network error"))]
28 MsgNetworkWriteBody { source: std::io::Error },
29 #[snafu(display("write `codec_msg` to network error"))]
30 MsgNetworkWriteCodecMsg { source: std::io::Error },
31 #[snafu(display("write `codec_tag` to network error"))]
32 MsgNetworkWriteCodecTag { source: std::io::Error },
33 #[snafu(display(
34 "`datalen` exceeded! the length must be less than {max}, but the actual length is {actual}"
35 ))]
36 MsgDatalenExceeded {
37 actual: DataLenType,
38 max: DataLenType,
39 },
40 #[snafu(display(
41 "`datalen` not valid,`datalen:{datalen}` doesn't pass the `checksum:{checksum}`"
42 ))]
43 MsgDatalenValidate {
44 datalen: DataLenType,
45 checksum: ChecksumType,
46 },
47 #[snafu(display("{action} `{struct_name}` error with content:{content}"))]
48 MsgSerialize {
49 action: &'static str,
51 struct_name: &'static str,
53 content: String,
55 source: serde_json::Error,
56 },
57 #[snafu(display("`{action}` failed with the specific error: `{detail}`"))]
58 MsgCodec {
59 action: &'static str,
61 detail: String,
63 },
64 #[snafu(display("protocol-v2 error: {detail}"))]
65 MsgProtocol { detail: String },
66 #[snafu(display("`{action}` forward message failed: {source}"))]
67 MsgForward {
68 action: &'static str,
70 source: std::io::Error,
71 },
72 #[snafu(display("failed to forward message to write in normal text"))]
74 FwdNetworkWriteWithNormal { source: std::io::Error },
75 #[snafu(display("parse socket address from string:`{string}` error"))]
77 CfgParseSockAddr {
78 string: String,
79 source: AddrParseError,
80 },
81 #[snafu(display("`PB_MAPPER_SERVER` env not set"))]
82 CfgPbServerEnvNotExist { source: VarError },
83}
84
85pub type Result<T, E = Error> = std::result::Result<T, E>;
86
87impl Error {
88 pub fn is_expected_disconnect(&self) -> bool {
89 use std::io::ErrorKind;
90
91 let is_expected = |kind: ErrorKind| {
92 matches!(
93 kind,
94 ErrorKind::UnexpectedEof
95 | ErrorKind::ConnectionReset
96 | ErrorKind::ConnectionAborted
97 | ErrorKind::BrokenPipe
98 | ErrorKind::NotConnected
99 | ErrorKind::TimedOut
100 )
101 };
102
103 match self {
104 Error::MsgNetworkReadCheckSum { source }
105 | Error::MsgNetworkReadDatalen { source }
106 | Error::MsgNetworkReadBufferdRawData { source }
107 | Error::MsgNetworkReadBody { source }
108 | Error::MsgNetworkWriteCheckSum { source }
109 | Error::MsgNetworkWriteDatalen { source }
110 | Error::MsgNetworkWriteBody { source }
111 | Error::MsgNetworkWriteCodecMsg { source }
112 | Error::MsgNetworkWriteCodecTag { source }
113 | Error::FwdNetworkWriteWithNormal { source }
114 | Error::MsgForward { source, .. } => is_expected(source.kind()),
115 _ => false,
116 }
117 }
118}
119
120#[macro_export]
121macro_rules! snafu_error_handle {
122 ($func_call:expr) => {
123 if let Err(e) = $func_call {
124 tracing::error!("{}", snafu::Report::from_error(e));
125 }
126 };
127 ($func_call:expr, $msg:expr) => {
128 if let Err(e) = $func_call {
129 tracing::error!("{},detail:{}", $msg, snafu::Report::from_error(e));
130 }
131 };
132}
133
134#[macro_export]
135macro_rules! snafu_error_get_or_continue {
136 ($func_call:expr) => {
137 match $func_call {
138 Ok(v) => v,
139 Err(e) => {
140 tracing::error!("{}", snafu::Report::from_error(e));
141 continue;
142 }
143 }
144 };
145 ($func_call:expr, $msg:expr) => {
146 match $func_call {
147 Ok(v) => v,
148 Err(e) => {
149 tracing::error!("{},detail:{}", $msg, snafu::Report::from_error(e));
150 continue;
151 }
152 }
153 };
154}
155
156#[macro_export]
157macro_rules! snafu_error_get_or_return {
158 ($func_call:expr) => {
159 match $func_call {
160 Ok(v) => v,
161 Err(e) => {
162 tracing::error!("{}", snafu::Report::from_error(e));
163 return;
164 }
165 }
166 };
167 ($func_call:expr, $msg:expr) => {
168 match $func_call {
169 Ok(v) => v,
170 Err(e) => {
171 tracing::error!("{},detail:{}", $msg, snafu::Report::from_error(e));
172 return;
173 }
174 }
175 };
176 ($func_call:expr, $msg:expr, $ret_val:expr) => {
177 match $func_call {
178 Ok(v) => v,
179 Err(e) => {
180 tracing::error!("{},detail:{}", $msg, snafu::Report::from_error(e));
181 return $ret_val;
182 }
183 }
184 };
185}
186
187#[macro_export]
188macro_rules! snafu_error_get_or_return_ok {
189 ($func_call:expr) => {
190 match $func_call {
191 Ok(v) => v,
192 Err(e) => {
193 tracing::error!("{}", snafu::Report::from_error(e));
194 return Ok(());
195 }
196 }
197 };
198 ($func_call:expr, $msg:expr) => {
199 match $func_call {
200 Ok(v) => v,
201 Err(e) => {
202 tracing::error!("{},detail:{}", $msg, snafu::Report::from_error(e));
203 return Ok(());
204 }
205 }
206 };
207}