use thiserror::Error;
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum RpcError {
#[error(transparent)]
AddrParseError(#[from] std::net::AddrParseError),
#[error("Could not parse UUID '{0}': {1}")]
UuidParseError(String, uuid::Error),
#[error(transparent)]
TransportError(#[from] tonic::transport::Error),
#[error("Internal Error: {0}")]
InternalError(String),
#[error("No inherent data found in RPC message")]
NoInherentData,
#[error("Could not convert type to or from gRPC to wick.")]
TypeConversion,
#[error("Invalid component kind {0}")]
InvalidComponentKind(i32),
#[error("{0}")]
Component(String),
#[error("Component did not include a supported feature list.")]
MissingFeatures,
#[error("{0}")]
Operation(String),
#[error("Error sending output to channel")]
SendError,
#[error("General error : {0}")]
General(String),
#[error("Deserialization Failed : {0}")]
Deserialization(String),
#[error("Internal Error : {0}")]
Internal(&'static str),
#[error("Configuration for invocation was empty.")]
ConfigEmpty,
#[error("State for invocation was missing.")]
StateMissing,
#[error("Invalid signature")]
InvalidSignature,
}
impl RpcError {
pub fn boxed<T: std::fmt::Display>(msg: T) -> Box<Self> {
Box::new(RpcError::General(msg.to_string()))
}
}
impl From<tokio::task::JoinError> for RpcError {
fn from(e: tokio::task::JoinError) -> Self {
RpcError::InternalError(format!("Tokio Error: {}", e))
}
}
impl From<std::io::Error> for RpcError {
fn from(e: std::io::Error) -> Self {
RpcError::InternalError(format!("IO Error: {}", e))
}
}
impl From<Box<dyn std::error::Error + Send + Sync>> for RpcError {
fn from(e: Box<dyn std::error::Error + Send + Sync>) -> Self {
RpcError::Component(e.to_string())
}
}
impl From<&str> for RpcError {
fn from(e: &str) -> Self {
RpcError::General(e.to_owned())
}
}
impl From<String> for RpcError {
fn from(e: String) -> Self {
RpcError::General(e)
}
}
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
pub enum RpcClientError {
#[error("RPC List call failed: {0}")]
ListCallFailed(tonic::Status),
#[error("RPC Invocation failed: {0}")]
InvocationFailed(tonic::Status),
#[error("RPC Stats call failed: {0}")]
StatsCallFailed(tonic::Status),
#[error("RPC response invalid: {0}")]
ResponseInvalid(String),
#[error(transparent)]
ConversionFailed(RpcError),
#[error("Could not convert type to or from gRPC to wick: {0}")]
TypeConversion(String),
#[error("I/O error: {0}")]
IO(std::io::Error),
#[error("Tls error: {0}")]
TlsError(tonic::transport::Error),
#[error("{0}")]
ConnectionError(String),
#[error("unspecified connection error")]
UnspecifiedConnectionError,
#[error("Connection failed: {0}")]
ConnectionFailed(String),
#[error("{0}")]
Other(String),
}
impl From<std::io::Error> for RpcClientError {
fn from(e: std::io::Error) -> Self {
RpcClientError::IO(e)
}
}
#[cfg(test)]
mod test {
use super::*;
const fn sync_send<T>()
where
T: Sync + Send,
{
}
#[test]
const fn test_sync_send() {
sync_send::<RpcError>();
sync_send::<RpcClientError>();
}
}