diff options
Diffstat (limited to 'src/error.rs')
-rw-r--r-- | src/error.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/error.rs b/src/error.rs index 7e68288..4ae2995 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,15 +1,72 @@ use bcrypt::BcryptError; use diesel::result::Error as DieselErr; +use serde_json::Value; use std::convert::From; use std::error::Error as StdError; use std::fmt; #[derive(Debug)] +pub struct StravaApiError{ + status: reqwest::StatusCode, + code: String, + field: String, + value: Value, +} + +impl StravaApiError { + pub fn new(status: reqwest::StatusCode, value: Value) -> StravaApiError { + let first_error = &value["errors"][0]; + + let code = first_error["code"].as_str().unwrap_or("unknown").to_string(); + let field = first_error["field"].as_str().unwrap_or("unknown").to_string(); + + StravaApiError { status, code, field, value } + } + } + +impl fmt::Display for StravaApiError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "field '{}' has error '{}'", self.field, self.code) + } +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn strava_api_error_unknown() { + let data = r#""insane input""#; + let json = serde_json::from_str(data).unwrap(); + let error = Error::StravaApiError(StravaApiError::new(reqwest::StatusCode::UNAUTHORIZED, json)); + assert_eq!("field 'unknown' has error 'unknown'", + format!("{}", error)); + } + + #[test] + fn strava_api_error_invalid() { + let data = r#" + { + "errors":[ + {"code":"invalid", + "field":"access_token", + "resource":"Athlete"} + ], + "message":"Authorization Error" + }"#; + let json = serde_json::from_str(data).unwrap(); + let error = Error::StravaApiError(StravaApiError::new(reqwest::StatusCode::UNAUTHORIZED, json)); + assert_eq!("field 'access_token' has error 'invalid'", + format!("{}", error)); + } +} + +#[derive(Debug)] pub enum Error { DieselError(DieselErr), PasswordError(BcryptError), CommunicationError(reqwest::Error), ParseError(serde_json::error::Error), + StravaApiError(StravaApiError), AlreadyExists, NotFound, InternalError, @@ -22,6 +79,7 @@ impl fmt::Display for Error { Error::PasswordError(ref e) => e.fmt(f), Error::CommunicationError(ref e) => e.fmt(f), Error::ParseError(ref e) => e.fmt(f), + Error::StravaApiError(ref e) => e.fmt(f), Error::AlreadyExists => f.write_str("AlreadyExists"), Error::NotFound => f.write_str("NotFound"), Error::InternalError => f.write_str("InternalError"), @@ -29,6 +87,12 @@ impl fmt::Display for Error { } } +impl From<StravaApiError> for Error { + fn from(e: StravaApiError) -> Error { + Error::StravaApiError(e) + } +} + impl From<serde_json::error::Error> for Error { fn from(e: serde_json::error::Error) -> Error { Error::ParseError(e) |