Skip to main content

pb_mapper_core/
error.rs

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// The generated context selectors are constructed by the protocol, client, and
11// server crates, so they have to be reachable from outside this one.
12#[snafu(visibility(pub))]
13pub enum Error {
14    /// Error handling for message
15    #[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        // must be "encode" or "decode"
50        action: &'static str,
51        // must be the name of the structure to be serialized,such as `PbConnRequest`
52        struct_name: &'static str,
53        // must be structures that need to be serialized or messages that need to be deserialized
54        content: String,
55        source: serde_json::Error,
56    },
57    #[snafu(display("`{action}` failed with the specific error: `{detail}`"))]
58    MsgCodec {
59        // must be "encrypt" or "decrypt" or "create encodec" or "create decodec"
60        action: &'static str,
61        // specific error explanation
62        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        // must be "read" or "write"
69        action: &'static str,
70        source: std::io::Error,
71    },
72    /// Error for forward
73    #[snafu(display("failed to forward message to write in normal text"))]
74    FwdNetworkWriteWithNormal { source: std::io::Error },
75    /// Error for config
76    #[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}