use arcbox_error::CommonError;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, ApiError>;
#[derive(Debug, Error)]
pub enum ApiError {
#[error(transparent)]
Common(#[from] CommonError),
#[error("core error: {0}")]
Core(#[from] arcbox_core::CoreError),
#[error("server error: {0}")]
Server(String),
#[error("transport error: {0}")]
Transport(String),
}
impl From<std::io::Error> for ApiError {
fn from(err: std::io::Error) -> Self {
Self::Common(CommonError::from(err))
}
}
impl From<ApiError> for connectrpc::ConnectError {
fn from(err: ApiError) -> Self {
use connectrpc::ErrorCode;
let message = err.to_string();
let code = match &err {
ApiError::Common(common) => match common {
CommonError::Config(_) => ErrorCode::InvalidArgument,
CommonError::NotFound(_) => ErrorCode::NotFound,
CommonError::AlreadyExists(_) => ErrorCode::AlreadyExists,
CommonError::InvalidState(_) => ErrorCode::FailedPrecondition,
CommonError::Timeout(_) => ErrorCode::DeadlineExceeded,
CommonError::PermissionDenied(_) => ErrorCode::PermissionDenied,
_ => ErrorCode::Internal,
},
ApiError::Core(arcbox_core::CoreError::Agent { code, .. }) => match code {
400 => ErrorCode::InvalidArgument,
404 => ErrorCode::NotFound,
409 => ErrorCode::AlreadyExists,
412 => ErrorCode::FailedPrecondition,
416 => ErrorCode::OutOfRange,
503 => ErrorCode::Unavailable,
_ => ErrorCode::Internal,
},
_ => ErrorCode::Internal,
};
Self::new(code, message)
}
}
impl ApiError {
#[must_use]
pub fn config(msg: impl Into<String>) -> Self {
Self::Common(CommonError::config(msg))
}
}