1use actix_web::{http::StatusCode, HttpResponse};
2use rustical_xml::XmlError;
3use thiserror::Error;
4use tracing::error;
5
6#[derive(Debug, Error)]
7pub enum Error {
8 #[error("Not found")]
9 NotFound,
10
11 #[error("Bad request: {0}")]
12 BadRequest(String),
13
14 #[error("Unauthorized")]
15 Unauthorized,
16
17 #[error("Internal server error :(")]
18 InternalError,
19
20 #[error("prop is read-only")]
21 PropReadOnly,
22
23 #[error(transparent)]
24 XmlError(#[from] rustical_xml::XmlError),
25
26 #[error(transparent)]
27 IOError(#[from] std::io::Error),
28}
29
30impl actix_web::error::ResponseError for Error {
31 fn status_code(&self) -> StatusCode {
32 match self {
33 Self::InternalError => StatusCode::INTERNAL_SERVER_ERROR,
34 Self::NotFound => StatusCode::NOT_FOUND,
35 Self::BadRequest(_) => StatusCode::BAD_REQUEST,
36 Self::Unauthorized => StatusCode::UNAUTHORIZED,
37 Self::XmlError(error) => match &error {
38 XmlError::InvalidTag(..)
39 | XmlError::MissingField(_)
40 | XmlError::UnsupportedEvent(_)
41 | XmlError::InvalidVariant(_)
42 | XmlError::InvalidFieldName(_, _)
43 | XmlError::InvalidValue(_) => StatusCode::UNPROCESSABLE_ENTITY,
44 _ => StatusCode::BAD_REQUEST,
45 },
46 Error::PropReadOnly => StatusCode::CONFLICT,
47 Self::IOError(_) => StatusCode::INTERNAL_SERVER_ERROR,
48 }
49 }
50
51 fn error_response(&self) -> HttpResponse {
52 error!("Error: {self}");
53 match self {
54 Error::Unauthorized => HttpResponse::build(self.status_code())
55 .append_header(("WWW-Authenticate", "Basic"))
56 .body(self.to_string()),
57 _ => HttpResponse::build(self.status_code()).body(self.to_string()),
58 }
59 }
60}