use std::io;
use tokio::{sync::watch, task::JoinError};
use veilid_core::VeilidAPIError;
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("veilid (unrecoverable): {0}")]
Unrecoverable(VeilidAPIError),
#[error("veilid (down): {0}")]
Down(VeilidAPIError),
#[error("routing: {0}")]
Routing(VeilidAPIError),
#[error("veilid: {0}")]
Veilid(VeilidAPIError),
#[error("io: {0}")]
IO(#[from] io::Error),
#[error("watch (receive): {0}")]
WatchReceive(#[from] watch::error::RecvError),
#[error("close: {0}")]
Close(#[from] JoinError),
}
pub type Result<T> = std::result::Result<T, Error>;
impl TryFrom<Error> for VeilidAPIError {
type Error = anyhow::Error;
fn try_from(err: Error) -> std::result::Result<Self, Self::Error> {
match err {
Error::Unrecoverable(veilid_apierror) => Ok(veilid_apierror),
Error::Down(veilid_apierror) => Ok(veilid_apierror),
Error::Veilid(veilid_apierror) => Ok(veilid_apierror),
e => Err(anyhow::anyhow!("{}: not a veilid error", e)),
}
}
}
impl From<VeilidAPIError> for Error {
fn from(err: VeilidAPIError) -> Self {
match err {
VeilidAPIError::Shutdown => Self::Unrecoverable(err),
VeilidAPIError::NoConnection { .. } => Self::Down(err),
VeilidAPIError::NotInitialized => Self::Down(err),
VeilidAPIError::InvalidTarget { .. } => Self::Routing(err),
VeilidAPIError::Generic { ref message } => match message.as_str() {
"can't reach private route any more" => Self::Routing(err),
"allocated route failed to test" => Self::Routing(err),
"allocated route could not be tested" => Self::Routing(err),
_ => Self::Veilid(err),
},
VeilidAPIError::TryAgain { ref message } => match message.as_str() {
"unable to allocate route until we have a valid PublicInternet network class" => {
Self::Routing(err)
}
"not enough nodes to construct route at this time" => Self::Routing(err),
"unable to find unique route at this time" => Self::Routing(err),
"unable to assemble route until we have published peerinfo" => Self::Routing(err),
_ => Self::Veilid(err),
},
VeilidAPIError::Internal { ref message } => match message.as_str() {
"no best key to test allocated route" => Self::Routing(err),
"peer info should exist for route but doesn't" => Self::Routing(err),
"route id does not exist" => Self::Routing(err),
_ => Self::Veilid(err),
},
_ => Self::Veilid(err),
}
}
}