thoth_api/
errors.rs

1#[cfg(feature = "backend")]
2use actix_web::{error::ResponseError, HttpResponse};
3#[cfg(feature = "backend")]
4use diesel::result::Error as DBError;
5use failure::Fail;
6
7pub type Result<T> = std::result::Result<T, failure::Error>;
8
9#[derive(Fail, Debug)]
10pub enum ThothError {
11    #[fail(display = "{} is not a valid {} code", _0, _1)]
12    InvalidSubjectCode(String, String),
13    #[fail(display = "{} is not a valid Language Code", _0)]
14    InvalidLanguageCode(String),
15    #[fail(display = "{} is not a valid Work Type", _0)]
16    InvalidWorkType(String),
17    #[fail(display = "{} is not a valid Work Status", _0)]
18    InvalidWorkStatus(String),
19    #[fail(display = "{} is not a valid Contribution Type", _0)]
20    InvalidContributionType(String),
21    #[fail(display = "{} is not a valid Publication Type", _0)]
22    InvalidPublicationType(String),
23    #[fail(display = "{} is not a valid Series Type", _0)]
24    InvalidSeriesType(String),
25    #[fail(display = "{} is not a valid Subject Type", _0)]
26    InvalidSubjectType(String),
27    #[fail(display = "{} is not a valid Language Relation", _0)]
28    InvalidLanguageRelation(String),
29    #[fail(display = "Database error: {}", _0)]
30    DatabaseError(String),
31    #[fail(display = "Internal error: {}", _0)]
32    InternalError(String),
33    #[fail(display = "Invalid credentials.")]
34    Unauthorised,
35    #[fail(display = "Failed to validate token.")]
36    InvalidToken,
37    #[fail(display = "No cookie found.")]
38    CookieError(),
39}
40
41impl juniper::IntoFieldError for ThothError {
42    fn into_field_error(self) -> juniper::FieldError {
43        match self {
44            ThothError::InvalidSubjectCode { .. } => juniper::FieldError::new(
45                self.to_string(),
46                graphql_value!({
47                    "type": "INVALID_SUBJECT_CODE"
48                }),
49            ),
50            ThothError::Unauthorised => juniper::FieldError::new(
51                "Unauthorized",
52                graphql_value!({
53                    "type": "NO_ACCESS"
54                }),
55            ),
56            _ => juniper::FieldError::new(
57                self.to_string(),
58                graphql_value!({
59                    "type": "INTERNAL_ERROR"
60                }),
61            ),
62        }
63    }
64}
65
66#[cfg(feature = "backend")]
67impl ResponseError for ThothError {
68    fn error_response(&self) -> HttpResponse {
69        match self {
70            ThothError::Unauthorised => HttpResponse::Unauthorized().json("Unauthorized"),
71            ThothError::DatabaseError { .. } => {
72                HttpResponse::InternalServerError().json("DB error")
73            }
74            _ => HttpResponse::InternalServerError().json("Internal error"),
75        }
76    }
77}
78
79#[cfg(feature = "backend")]
80impl From<DBError> for ThothError {
81    fn from(error: DBError) -> ThothError {
82        match error {
83            DBError::DatabaseError(_kind, info) => {
84                let message = info.details().unwrap_or_else(|| info.message()).to_string();
85                ThothError::DatabaseError(message)
86            }
87            _ => ThothError::InternalError("".into()),
88        }
89    }
90}
91
92impl From<std::io::Error> for ThothError {
93    fn from(error: std::io::Error) -> ThothError {
94        ThothError::InternalError(error.to_string())
95    }
96}
97
98impl From<reqwest::Error> for ThothError {
99    fn from(error: reqwest::Error) -> ThothError {
100        ThothError::InternalError(error.to_string())
101    }
102}
103
104impl From<xml::writer::Error> for ThothError {
105    fn from(error: xml::writer::Error) -> ThothError {
106        ThothError::InternalError(error.to_string())
107    }
108}
109
110impl From<failure::Error> for ThothError {
111    fn from(error: failure::Error) -> ThothError {
112        if error.downcast_ref::<ThothError>().is_some() {
113            return error.downcast::<ThothError>().unwrap();
114        }
115        ThothError::InternalError(error.to_string())
116    }
117}