use std; use std::fmt; use std::convert::From; use rusqlite; use iron::{IronError, status}; use iron::headers::ContentType; use iron::modifiers::Header; #[derive(Debug)] pub enum LinoError { DbError(rusqlite::Error), IoError(std::io::Error), NotFound(String), BadRequest(String), } pub type Result = std::result::Result; impl fmt::Display for LinoError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { LinoError::DbError(ref err) => err.fmt(f), LinoError::IoError(ref err) => err.fmt(f), LinoError::NotFound(ref x) => write!(f, "Could not find {}", x), LinoError::BadRequest(ref x) => write!(f, "Bad request: {}", x), } } } impl std::error::Error for LinoError { fn description(&self) -> &str { match *self { LinoError::DbError(ref err) => err.description(), LinoError::IoError(ref err) => err.description(), LinoError::NotFound(_) => "not found", LinoError::BadRequest(_) => "bad request", } } fn cause(&self) -> Option<&std::error::Error> { match *self { LinoError::DbError(ref err) => Some(err), LinoError::IoError(ref err) => Some(err), LinoError::NotFound(_) => None, LinoError::BadRequest(_) => None, } } } impl From for LinoError { fn from(err: rusqlite::Error) -> LinoError { LinoError::DbError(err) } } impl From for LinoError { fn from(err: std::io::Error) -> LinoError { LinoError::IoError(err) } } impl From for IronError { fn from(err: LinoError) -> IronError { let code = match err { LinoError::NotFound(_) => status::NotFound, LinoError::BadRequest(_) => status::BadRequest, _ => status::InternalServerError, }; let description = format!("{:?}", err); IronError::new(err, (code, Header(ContentType::html()), description)) } }