Skip to main content

pib_service_api/
error.rs

1// SPDX-FileCopyrightText: Politik im Blick developers
2// SPDX-FileCopyrightText: Wolfgang Silbermayr <wolfgang@silbermayr.at>
3//
4// SPDX-License-Identifier: AGPL-3.0-or-later OR EUPL-1.2
5
6use axum::{
7    Json,
8    http::StatusCode,
9    response::{IntoResponse, Response},
10};
11use serde::{Deserialize, Serialize};
12use snafu::{IntoError, Snafu};
13
14#[derive(Debug, Snafu)]
15pub enum Error {
16    Service { source: pib_service_facade::Error },
17}
18
19#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
20pub struct ApiError {
21    pub message: String,
22}
23
24impl IntoResponse for Error {
25    fn into_response(self) -> Response {
26        let mut response = Json(ApiError {
27            message: format!("{self}"),
28        })
29        .into_response();
30        *response.status_mut() = if self.is_not_found() {
31            StatusCode::NOT_FOUND
32        } else if self.is_forbidden() {
33            StatusCode::FORBIDDEN
34        } else if self.is_bad_request() {
35            StatusCode::BAD_REQUEST
36        } else {
37            StatusCode::INTERNAL_SERVER_ERROR
38        };
39        response
40    }
41}
42
43impl Error {
44    pub fn is_not_found(&self) -> bool {
45        matches!(
46            self,
47            Error::Service{source} if source.is_not_found()
48        )
49    }
50
51    pub fn is_forbidden(&self) -> bool {
52        matches!(self, Error::Service{source} if source.is_forbidden())
53    }
54
55    pub fn is_bad_request(&self) -> bool {
56        matches!(self, Error::Service{source} if source.is_bad_request())
57    }
58}
59
60impl From<pib_service_facade::Error> for Error {
61    fn from(source: pib_service_facade::Error) -> Self {
62        ServiceSnafu.into_error(source)
63    }
64}