1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use std::error::Error as StdError;
use std::fmt::Debug;
use std::fmt::{Display, Formatter, Result as FmtResult};
use tokio::sync::mpsc::error::SendError;
use tonic::transport::Error as TonicError;
#[macro_export]
macro_rules! function {
() => {{
fn f() {}
fn type_name_of<T>(_: T) -> &'static str {
std::any::type_name::<T>()
}
let name = type_name_of(f);
&name[..name.len() - 3]
}};
}
#[macro_export]
macro_rules! log_and_escalate {
($e:expr) => {
match $e {
Err(err) => {
log::error!("{},({}:{}), {:?}", function!(), file!(), line!(), err);
return Err(Error::from(err));
}
Ok(o) => o,
}
};
}
#[macro_export]
macro_rules! log_and_escalate_status {
($e:expr) => {
match $e {
Err(err) => {
log::error!("{},({}:{}), {:?}", function!(), file!(), line!(), err);
return Err(tonic::Status::unknown(format!("{:?}", err)));
}
Ok(o) => o,
}
};
}
#[derive(Debug)]
pub enum Error {
NoTCPPortAvailable,
GRPCHandshakeMagicCookieValueMismatch,
Io(std::io::Error),
Generic(String),
TonicTransport(TonicError),
AddrParser(std::net::AddrParseError),
Send(String),
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
Self::NoTCPPortAvailable => write!(
f,
"No ports were available to bind the plugin's gRPC server to."
),
Self::GRPCHandshakeMagicCookieValueMismatch => write!(f, "This executable is meant to be a go-plugin to other processes. Do not run this directly. The Magic Handshake failed."),
Self::Generic(s) => write!(f, "{}", s),
Self::Io(e) => write!(f, "Error with IO: {:?}", e),
Self::TonicTransport(e) => write!(f, "Error with tonic (gRPC) transport: {:?}", e),
Self::AddrParser(e) => write!(f, "Error parsing string into a network address: {:?}", e),
Self::Send(s) => write!(f, "Error sending on a mpsc channel: {}", s),
}
}
}
impl StdError for Error {}
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
Self::Io(err)
}
}
impl From<TonicError> for Error {
fn from(err: TonicError) -> Self {
Self::TonicTransport(err)
}
}
impl From<std::net::AddrParseError> for Error {
fn from(err: std::net::AddrParseError) -> Self {
Self::AddrParser(err)
}
}
impl<T> From<SendError<T>> for Error {
fn from(_err: SendError<T>) -> Self {
Self::Send(format!(
"unable to send {} on a mpsc channel",
std::any::type_name::<T>()
))
}
}