From fdc1abe7cc6e2552c30df6c124aca711b130d496 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sun, 8 Apr 2018 19:21:56 +0200 Subject: feat(errors): Introduce error module with custom error type Introduces an error type using the failure crate. This type has foreign error links established to various errors that can occur within Converse. --- src/errors.rs | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 8 +++++-- 2 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 src/errors.rs (limited to 'src') 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 = result::Result; + +#[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 }, +} + +// Establish conversion links to foreign errors: + +impl From for ConverseError { + fn from(error: diesel::result::Error) -> ConverseError { + ConverseError::Database { error } + } +} + +impl From for ConverseError { + fn from(error: r2d2::Error) -> ConverseError { + ConverseError::ConnectionPool { error } + } +} + +impl From for ConverseError { + fn from(error: tera::Error) -> ConverseError { + ConverseError::Template { + reason: format!("{}", error), + } + } +} + +impl From 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::*; -- cgit 1.4.1