raspberry_web/
errors.rs

1// https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/wrap_error.html
2// https://stevedonovan.github.io/rust-gentle-intro/6-error-handling.html
3
4use actix_web::error::ResponseError;
5use diesel::result::Error as dieselError;
6#[cfg(target_arch = "arm")]
7use rppal::gpio::Error as rppalError;
8use std::env::VarError as stdVarError;
9use std::io::Error as stdIoError;
10use std::num::ParseIntError as numParseIntError;
11
12use std::error;
13use std::fmt;
14
15#[derive(Debug)]
16pub enum RpWebError {
17    // Defer to other error type implementation.
18    ParseIntError(numParseIntError),
19    VarError(stdVarError),
20    IoError(stdIoError),
21    DbError(dieselError),
22    #[cfg(target_arch = "arm")]
23    GpioError(rppalError),
24    Generic(String),
25}
26
27/// RpWebError::new("error string")
28impl RpWebError {
29    pub fn new(message: &str) -> RpWebError {
30        RpWebError::Generic(message.to_string())
31    }
32}
33
34impl fmt::Display for RpWebError {
35    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
36        match *self {
37            // This is a wrapper, so defer to the underlying types' implementation of `fmt`.
38            RpWebError::ParseIntError(ref err) => err.fmt(formatter),
39            RpWebError::VarError(ref err) => err.fmt(formatter),
40            RpWebError::IoError(ref err) => err.fmt(formatter),
41            RpWebError::DbError(ref err) => err.fmt(formatter),
42            #[cfg(target_arch = "arm")]
43            RpWebError::GpioError(ref err) => err.fmt(formatter),
44            RpWebError::Generic(ref errs) => write!(formatter, "{}", errs),
45        }
46    }
47}
48
49impl error::Error for RpWebError {
50    fn description(&self) -> &str {
51        match *self {
52            // These already impls `Error`, so defer to its own implementation.
53            RpWebError::ParseIntError(ref err) => err.description(),
54            RpWebError::VarError(ref err) => err.description(),
55            RpWebError::IoError(ref err) => err.description(),
56            RpWebError::DbError(ref err) => err.description(),
57            #[cfg(target_arch = "arm")]
58            RpWebError::GpioError(ref err) => err.description(),
59            RpWebError::Generic(ref _errs) => "Generic RpWebError",
60        }
61    }
62
63    fn cause(&self) -> Option<&error::Error> {
64        match *self {
65            // The cause is the underlying implementation error type. Is implicitly
66            // cast to the trait object `&error::Error`. This number because the
67            // underlying type already implements the `Error` trait.
68            RpWebError::ParseIntError(ref err) => Some(err),
69            RpWebError::VarError(ref err) => Some(err),
70            RpWebError::IoError(ref err) => Some(err),
71            RpWebError::DbError(ref err) => Some(err),
72            #[cfg(target_arch = "arm")]
73            RpWebError::GpioError(ref err) => Some(err),
74            RpWebError::Generic(ref _errs) => None,
75        }
76    }
77}
78
79// Implement the conversion from `<E>` to `RpWebError`.
80// This will be automatically called by `?` if an `<E>>`
81// needs to be converted into a `RpWebError`.
82impl From<numParseIntError> for RpWebError {
83    fn from(err: numParseIntError) -> RpWebError {
84        RpWebError::ParseIntError(err)
85    }
86}
87
88impl From<stdVarError> for RpWebError {
89    fn from(err: stdVarError) -> RpWebError {
90        RpWebError::VarError(err)
91    }
92}
93
94impl From<stdIoError> for RpWebError {
95    fn from(err: stdIoError) -> RpWebError {
96        RpWebError::IoError(err)
97    }
98}
99
100impl From<dieselError> for RpWebError {
101    fn from(err: dieselError) -> RpWebError {
102        RpWebError::DbError(err)
103    }
104}
105
106#[cfg(target_arch = "arm")]
107impl From<rppalError> for RpWebError {
108    fn from(err: rppalError) -> RpWebError {
109        RpWebError::GpioError(err)
110    }
111}
112
113// Avoids the trait `actix_web::error::ResponseError` is not implemented for `RpWebError`
114// https://github.com/actix/actix-website/blob/master/content/docs/errors.md
115// Use default implementation for `error_response()` method
116impl ResponseError for RpWebError {}