use tonic::{Code, Status};
#[derive(Debug, thiserror::Error)]
pub enum ConciergeError {
#[error("concierge refused the call: {code:?}")]
Refused { code: Code },
#[error("concierge rejected the request ({code:?}): {message}")]
Rejected { code: Code, message: String },
#[error("concierge is unavailable: {0}")]
Unavailable(String),
#[error("concierge answered something unusable: {0}")]
InvalidResponse(String),
#[error("concierge client misconfigured: {0}")]
Config(String),
#[error("no randomness for {what}: {source}")]
Randomness {
what: &'static str,
#[source]
source: getrandom::Error,
},
#[error("concierge failed ({code:?}): {message}")]
Failed { code: Code, message: String },
}
impl From<Status> for ConciergeError {
fn from(status: Status) -> Self {
let code = status.code();
let message = status.message().to_owned();
match code {
Code::Unauthenticated | Code::PermissionDenied => Self::Refused { code },
Code::InvalidArgument | Code::FailedPrecondition => Self::Rejected { code, message },
Code::Unavailable | Code::DeadlineExceeded | Code::Cancelled => Self::Unavailable(message),
Code::Ok
| Code::Unknown
| Code::NotFound
| Code::AlreadyExists
| Code::ResourceExhausted
| Code::Aborted
| Code::OutOfRange
| Code::Unimplemented
| Code::Internal
| Code::DataLoss => Self::Failed { code, message },
}
}
}
impl ConciergeError {
pub fn is_transient(&self) -> bool {
matches!(self, Self::Unavailable(_))
}
}