Skip to content
Clone
2308dd0
80 lines 2.0 KB Rust
use tonic::{Code, Status};
#[derive(Debug, thiserror::Error)]
pub enum KenShellError {
#[error("config: {0}")]
Config(String),
#[error("transport: {0}")]
Transport(#[from] tonic::transport::Error),
#[error("rpc {code:?}: {message}")]
Rpc { code: Code, message: String },
#[error("timeout")]
Timeout,
}
impl KenShellError {
pub fn from_status(status: Status) -> Self {
match status.code() {
Code::DeadlineExceeded => Self::Timeout,
code => Self::Rpc {
code,
message: status.message().to_string(),
},
}
}
pub fn code(&self) -> Option<Code> {
match self {
Self::Rpc { code, .. } => Some(*code),
Self::Timeout => Some(Code::DeadlineExceeded),
_ => None,
}
}
pub fn is_not_found(&self) -> bool {
self.code() == Some(Code::NotFound)
}
pub fn is_permission_denied(&self) -> bool {
self.code() == Some(Code::PermissionDenied)
}
pub fn is_invalid_argument(&self) -> bool {
self.code() == Some(Code::InvalidArgument)
}
pub fn is_unauthenticated(&self) -> bool {
self.code() == Some(Code::Unauthenticated)
}
pub fn is_conflict(&self) -> bool {
matches!(
self.code(),
Some(Code::Aborted) | Some(Code::AlreadyExists) | Some(Code::FailedPrecondition)
)
}
pub fn is_unavailable(&self) -> bool {
matches!(
self.code(),
Some(Code::Unavailable) | Some(Code::DeadlineExceeded)
)
}
pub fn message(&self) -> String {
match self {
Self::Config(message) => message.clone(),
Self::Transport(error) => error.to_string(),
Self::Rpc { message, .. } => message.clone(),
Self::Timeout => "deadline exceeded".to_string(),
}
}
}
impl From<Status> for KenShellError {
fn from(status: Status) -> Self {
Self::from_status(status)
}
}
pub type KenShellResult<T> = Result<T, KenShellError>;