You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.0 KiB

use std::fmt;
use std::error::Error as StdError;
use reqwest::Error as ReqError;
use serde::{
Serialize,
Deserialize
};
pub type BoxError = Box<(dyn StdError + Send + Sync + 'static)>;
pub type UResult<T> = std::result::Result<T, UError>;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum UErrType {
ConnectionError,
ParseError,
JobError,
Unknown,
Raw(String)
}
#[derive(Serialize, Deserialize, Clone, Debug)]
struct Inner {
err_type: UErrType,
source: Option<BoxError>
}
#[derive(Serialize, Deserialize, Clone)]
pub struct UError {
inner: Box<Inner>
}
impl UError {
pub fn new<E: Into<BoxError>>(err_type: UErrType, source: Option<E>) -> Self {
Self {
inner: Box::new(Inner {
source: source.map(Into::into),
err_type
})
}
}
}
impl fmt::Debug for UError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut builder = f.debug_struct("errors::UError");
builder.field("kind", &self.inner.err_type);
if let Some(ref source) = self.inner.source {
builder.field("source", source);
}
builder.finish()
}
}
impl fmt::Display for UError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let e_type = match self.inner.err_type {
UErrType::Raw(ref msg) => msg,
UErrType::ConnectionError => "Connection error",
UErrType::ParseError => "Parse error",
UErrType::JobError => "Job error",
UErrType::Unknown => "Unknown error",
};
f.write_str(e_type)?;
if let Some(ref e) = self.inner.source {
write!(f, ": {}", e)
} else {
Ok(())
}
}
}
impl From<ReqError> for UError {
fn from(e: ReqError) -> Self {
let err_type = if e.is_request() {
UErrType::ConnectionError
} else if e.is_decode() {
UErrType::ParseError
} else {
UErrType::Unknown
};
UError::new(err_type, Some(e))
}
}