use std::convert::From;
use std::error::Error as StdError;
use std::result::Result as StdResult;
use std::{
fmt,
fmt::{Display, Formatter},
};
use http;
use http::uri;
use hyper;
use serde_json;
use url;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub struct Error {
kind: ErrorKind,
}
#[derive(Debug)]
pub enum ErrorKind {
InvalidHost {
url: String,
err: url::ParseError,
},
InvalidApiUrl {
url: String,
err: uri::InvalidUri,
},
Http {
err: hyper::Error,
},
InvalidResponseJson {
err: serde_json::Error,
},
#[doc(hidden)]
__Nonexhaustive,
}
impl std::error::Error for Error {
fn cause(&self) -> Option<&dyn StdError> {
match self.kind {
ErrorKind::InvalidHost { ref err, .. } => Some(err),
ErrorKind::Http { ref err } => Some(err),
ErrorKind::InvalidResponseJson { ref err, .. } => Some(err),
_ => unreachable!("unexpected match arm!"),
}
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> StdResult<(), fmt::Error> {
match self.kind {
ErrorKind::InvalidHost { ref url, .. } => {
f.write_str(&format!("Invalid Prometheus host '{}'", url))
}
ErrorKind::Http { ref err } => err.fmt(f),
ErrorKind::InvalidApiUrl { ref url, .. } => {
f.write_str(&format!("Invalid API url '{}'", url))
}
ErrorKind::InvalidResponseJson { ref err, .. } => err.fmt(f),
_ => unreachable!("unexpected match arm!"),
}
}
}
impl Error {
pub(crate) fn new_invalid_host_error<S: Into<String>>(url: S, err: url::ParseError) -> Error {
Error {
kind: ErrorKind::InvalidHost {
url: url.into(),
err,
},
}
}
pub fn kind(&self) -> &ErrorKind {
&self.kind
}
}
impl From<hyper::Error> for Error {
fn from(err: hyper::Error) -> Self {
Error {
kind: ErrorKind::Http { err },
}
}
}
impl From<serde_json::Error> for Error {
fn from(err: serde_json::Error) -> Self {
Error {
kind: ErrorKind::InvalidResponseJson { err },
}
}
}
impl From<uri::InvalidUri> for Error {
fn from(err: uri::InvalidUri) -> Self {
Error {
kind: ErrorKind::InvalidApiUrl {
url: err.to_string(),
err,
},
}
}
}