use std::env::VarError;
use std::net::AddrParseError;
use snafu::Snafu;
use crate::DataLenType;
use crate::checksum::ChecksumType;
#[derive(Debug, Snafu)]
#[snafu(visibility(pub))]
pub enum Error {
#[snafu(display("read `checksum` from network error"))]
MsgNetworkReadCheckSum { source: std::io::Error },
#[snafu(display("read `datalen` from network error"))]
MsgNetworkReadDatalen { source: std::io::Error },
#[snafu(display("read `buffered_raw_data` from network error"))]
MsgNetworkReadBufferdRawData { source: std::io::Error },
#[snafu(display("read `msg_body` from network error"))]
MsgNetworkReadBody { source: std::io::Error },
#[snafu(display("write `checksum` to network error"))]
MsgNetworkWriteCheckSum { source: std::io::Error },
#[snafu(display("write `datalen` to network error"))]
MsgNetworkWriteDatalen { source: std::io::Error },
#[snafu(display("write `msg_body` to network error"))]
MsgNetworkWriteBody { source: std::io::Error },
#[snafu(display("write `codec_msg` to network error"))]
MsgNetworkWriteCodecMsg { source: std::io::Error },
#[snafu(display("write `codec_tag` to network error"))]
MsgNetworkWriteCodecTag { source: std::io::Error },
#[snafu(display(
"`datalen` exceeded! the length must be less than {max}, but the actual length is {actual}"
))]
MsgDatalenExceeded {
actual: DataLenType,
max: DataLenType,
},
#[snafu(display(
"`datalen` not valid,`datalen:{datalen}` doesn't pass the `checksum:{checksum}`"
))]
MsgDatalenValidate {
datalen: DataLenType,
checksum: ChecksumType,
},
#[snafu(display("{action} `{struct_name}` error with content:{content}"))]
MsgSerialize {
action: &'static str,
struct_name: &'static str,
content: String,
source: serde_json::Error,
},
#[snafu(display("`{action}` failed with the specific error: `{detail}`"))]
MsgCodec {
action: &'static str,
detail: String,
},
#[snafu(display("protocol-v2 error: {detail}"))]
MsgProtocol { detail: String },
#[snafu(display("`{action}` forward message failed: {source}"))]
MsgForward {
action: &'static str,
source: std::io::Error,
},
#[snafu(display("failed to forward message to write in normal text"))]
FwdNetworkWriteWithNormal { source: std::io::Error },
#[snafu(display("parse socket address from string:`{string}` error"))]
CfgParseSockAddr {
string: String,
source: AddrParseError,
},
#[snafu(display("`PB_MAPPER_SERVER` env not set"))]
CfgPbServerEnvNotExist { source: VarError },
}
pub type Result<T, E = Error> = std::result::Result<T, E>;
impl Error {
pub fn is_expected_disconnect(&self) -> bool {
use std::io::ErrorKind;
let is_expected = |kind: ErrorKind| {
matches!(
kind,
ErrorKind::UnexpectedEof
| ErrorKind::ConnectionReset
| ErrorKind::ConnectionAborted
| ErrorKind::BrokenPipe
| ErrorKind::NotConnected
| ErrorKind::TimedOut
)
};
match self {
Error::MsgNetworkReadCheckSum { source }
| Error::MsgNetworkReadDatalen { source }
| Error::MsgNetworkReadBufferdRawData { source }
| Error::MsgNetworkReadBody { source }
| Error::MsgNetworkWriteCheckSum { source }
| Error::MsgNetworkWriteDatalen { source }
| Error::MsgNetworkWriteBody { source }
| Error::MsgNetworkWriteCodecMsg { source }
| Error::MsgNetworkWriteCodecTag { source }
| Error::FwdNetworkWriteWithNormal { source }
| Error::MsgForward { source, .. } => is_expected(source.kind()),
_ => false,
}
}
}
#[macro_export]
macro_rules! snafu_error_handle {
($func_call:expr) => {
if let Err(e) = $func_call {
tracing::error!("{}", snafu::Report::from_error(e));
}
};
($func_call:expr, $msg:expr) => {
if let Err(e) = $func_call {
tracing::error!("{},detail:{}", $msg, snafu::Report::from_error(e));
}
};
}
#[macro_export]
macro_rules! snafu_error_get_or_continue {
($func_call:expr) => {
match $func_call {
Ok(v) => v,
Err(e) => {
tracing::error!("{}", snafu::Report::from_error(e));
continue;
}
}
};
($func_call:expr, $msg:expr) => {
match $func_call {
Ok(v) => v,
Err(e) => {
tracing::error!("{},detail:{}", $msg, snafu::Report::from_error(e));
continue;
}
}
};
}
#[macro_export]
macro_rules! snafu_error_get_or_return {
($func_call:expr) => {
match $func_call {
Ok(v) => v,
Err(e) => {
tracing::error!("{}", snafu::Report::from_error(e));
return;
}
}
};
($func_call:expr, $msg:expr) => {
match $func_call {
Ok(v) => v,
Err(e) => {
tracing::error!("{},detail:{}", $msg, snafu::Report::from_error(e));
return;
}
}
};
($func_call:expr, $msg:expr, $ret_val:expr) => {
match $func_call {
Ok(v) => v,
Err(e) => {
tracing::error!("{},detail:{}", $msg, snafu::Report::from_error(e));
return $ret_val;
}
}
};
}
#[macro_export]
macro_rules! snafu_error_get_or_return_ok {
($func_call:expr) => {
match $func_call {
Ok(v) => v,
Err(e) => {
tracing::error!("{}", snafu::Report::from_error(e));
return Ok(());
}
}
};
($func_call:expr, $msg:expr) => {
match $func_call {
Ok(v) => v,
Err(e) => {
tracing::error!("{},detail:{}", $msg, snafu::Report::from_error(e));
return Ok(());
}
}
};
}