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.
This commit is contained in:
parent
c8cee945c5
commit
fdc1abe7cc
4 changed files with 83 additions and 2 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -251,6 +251,7 @@ dependencies = [
|
||||||
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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)",
|
"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)",
|
"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)",
|
"r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -15,3 +15,4 @@ futures = "*"
|
||||||
tera = "0.11"
|
tera = "0.11"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
|
failure = "*"
|
||||||
|
|
75
src/errors.rs
Normal file
75
src/errors.rs
Normal file
|
@ -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))
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,9 @@ extern crate tera;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate failure;
|
||||||
|
|
||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
extern crate actix;
|
extern crate actix;
|
||||||
extern crate actix_web;
|
extern crate actix_web;
|
||||||
|
@ -18,10 +21,11 @@ extern crate r2d2;
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
|
|
||||||
pub mod schema;
|
|
||||||
pub mod models;
|
|
||||||
pub mod db;
|
pub mod db;
|
||||||
|
pub mod errors;
|
||||||
pub mod handlers;
|
pub mod handlers;
|
||||||
|
pub mod models;
|
||||||
|
pub mod schema;
|
||||||
|
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
use actix_web::*;
|
use actix_web::*;
|
||||||
|
|
Loading…
Reference in a new issue