about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2018-12-13T14·01+0100
committerVincent Ambo <mail@tazj.in>2018-12-13T14·01+0100
commite801b5853c1d06d1dc5cb43eadba0069b7e6fa85 (patch)
tree1a1065d28a9ce7ec431b25a0fddf943f88c100a6
parent68060fea13cdc26568b1a51e1bf4326885c23d63 (diff)
feat(postgres): Add human-readable Display implementation for errors
-rw-r--r--finito-postgres/src/error.rs33
1 files changed, 30 insertions, 3 deletions
diff --git a/finito-postgres/src/error.rs b/finito-postgres/src/error.rs
index aacc219f04..0bf7f40185 100644
--- a/finito-postgres/src/error.rs
+++ b/finito-postgres/src/error.rs
@@ -2,8 +2,9 @@
 //! occur while dealing with persisted state machines.
 
 use std::result;
-use std::fmt::Display;
+use std::fmt;
 use uuid::Uuid;
+use std::error::Error as StdError;
 
 // errors to chain:
 use serde_json::Error as JsonError;
@@ -32,6 +33,32 @@ pub enum ErrorKind {
     ActionNotFound(Uuid),
 }
 
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        use ErrorKind::*;
+        let msg = match &self.kind {
+            Serialization(err) =>
+                format!("JSON serialization error: {}", err),
+
+            Database(err) =>
+                format!("PostgreSQL error: {}", err),
+
+            FSMNotFound(id) =>
+                format!("FSM with ID {} not found", id),
+
+            ActionNotFound(id) =>
+                format!("Action with ID {} not found", id),
+        };
+
+        match &self.context {
+            None => write!(f, "{}", msg),
+            Some(ctx) => write!(f, "{}: {}", ctx, msg),
+        }
+    }
+}
+
+impl StdError for Error {}
+
 impl <E: Into<ErrorKind>> From<E> for Error {
     fn from(err: E) -> Error {
         Error {
@@ -56,11 +83,11 @@ impl From<PgError> for ErrorKind {
 /// Helper trait that makes it possible to supply contextual
 /// information with an error.
 pub trait ResultExt<T> {
-    fn context<C: Display>(self, ctx: C) -> Result<T>;
+    fn context<C: fmt::Display>(self, ctx: C) -> Result<T>;
 }
 
 impl <T, E: Into<Error>> ResultExt<T> for result::Result<T, E> {
-    fn context<C: Display>(self, ctx: C) -> Result<T> {
+    fn context<C: fmt::Display>(self, ctx: C) -> Result<T> {
         self.map_err(|err| Error {
             context: Some(format!("{}", ctx)),
             .. err.into()