about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@gmail.com>2018-04-08T17·21+0200
committerVincent Ambo <tazjin@gmail.com>2018-04-08T17·21+0200
commitfdc1abe7cc6e2552c30df6c124aca711b130d496 (patch)
tree3e53f364c168396f30ccc6a1f70f377ed62b1dda /src
parentc8cee945c569d71618b6bce5848233af4c9be18a (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/errors.rs75
-rw-r--r--src/main.rs8
2 files changed, 81 insertions, 2 deletions
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::*;