rustical_dav/
error.rs

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}