diff options
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/errors.rs | 75 | ||||
-rw-r--r-- | src/main.rs | 8 |
4 files changed, 83 insertions, 2 deletions
diff --git a/Cargo.lock b/Cargo.lock index 7b84193ebe77..50fdc3ba985f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -251,6 +251,7 @@ dependencies = [ "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "diesel 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 76dccad89b00..9bcfafac4f14 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,3 +15,4 @@ futures = "*" tera = "0.11" serde = "1.0" serde_derive = "1.0" +failure = "*" diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 000000000000..3cbda5f4e55d --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,75 @@ +//! This module defines custom error types using the `failure`-crate. +//! Links to foreign error types (such as database connection errors) +//! are established in a similar way as was tradition in +//! `error_chain`, albeit manually. + +use std::result; +use actix_web::{ResponseError, HttpResponse}; +use actix_web::http::StatusCode; + +// Modules with foreign errors: +use actix; +use diesel; +use r2d2; +use tera; + +pub type Result<T> = result::Result<T, ConverseError>; + +#[derive(Debug, Fail)] +pub enum ConverseError { + #[fail(display = "an internal Converse error occured: {}", reason)] + InternalError { reason: String }, + + #[fail(display = "a database error occured: {}", error)] + Database { error: diesel::result::Error }, + + #[fail(display = "a database connection pool error occured: {}", error)] + ConnectionPool { error: r2d2::Error }, + + #[fail(display = "a template rendering error occured: {}", reason)] + Template { reason: String }, + + // This variant is used as a catch-all for wrapping + // actix-web-compatible response errors, such as the errors it + // throws itself. + #[fail(display = "Actix response error: {}", error)] + ActixWeb { error: Box<ResponseError> }, +} + +// Establish conversion links to foreign errors: + +impl From<diesel::result::Error> for ConverseError { + fn from(error: diesel::result::Error) -> ConverseError { + ConverseError::Database { error } + } +} + +impl From<r2d2::Error> for ConverseError { + fn from(error: r2d2::Error) -> ConverseError { + ConverseError::ConnectionPool { error } + } +} + +impl From<tera::Error> for ConverseError { + fn from(error: tera::Error) -> ConverseError { + ConverseError::Template { + reason: format!("{}", error), + } + } +} + +impl From<actix::MailboxError> for ConverseError { + fn from(error: actix::MailboxError) -> ConverseError { + ConverseError::ActixWeb { error: Box::new(error) } + } +} + +// Support conversion of error type into HTTP error responses: + +impl ResponseError for ConverseError { + fn error_response(&self) -> HttpResponse { + // Everything is mapped to internal server errors for now. + HttpResponse::build(StatusCode::INTERNAL_SERVER_ERROR) + .body(format!("An error occured: {}", self)) + } +} diff --git a/src/main.rs b/src/main.rs index 8ce4e1082e4e..767d45891c3b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,9 @@ extern crate tera; #[macro_use] extern crate serde_derive; +#[macro_use] +extern crate failure; + extern crate chrono; extern crate actix; extern crate actix_web; @@ -18,10 +21,11 @@ extern crate r2d2; extern crate futures; extern crate serde; -pub mod schema; -pub mod models; pub mod db; +pub mod errors; pub mod handlers; +pub mod models; +pub mod schema; use actix::prelude::*; use actix_web::*; |