Skip to main content

gestalt/
error.rs

1#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
2#[error("{message}")]
3pub struct Error {
4    status: Option<u16>,
5    message: String,
6    expose_message: bool,
7}
8
9pub(crate) const HTTP_BAD_REQUEST: u16 = 400;
10pub(crate) const HTTP_NOT_FOUND: u16 = 404;
11pub(crate) const HTTP_INTERNAL_SERVER_ERROR: u16 = 500;
12pub(crate) const HTTP_NOT_IMPLEMENTED: u16 = 501;
13pub(crate) const INTERNAL_ERROR_MESSAGE: &str = "internal error";
14
15pub type Result<T> = std::result::Result<T, Error>;
16
17impl Error {
18    pub fn new(message: impl Into<String>) -> Self {
19        Self {
20            status: None,
21            message: message.into(),
22            expose_message: true,
23        }
24    }
25
26    pub fn with_status(status: u16, message: impl Into<String>) -> Self {
27        Self {
28            status: Some(status),
29            message: message.into(),
30            expose_message: true,
31        }
32    }
33
34    pub fn bad_request(message: impl Into<String>) -> Self {
35        Self::with_status(HTTP_BAD_REQUEST, message)
36    }
37
38    pub fn internal(message: impl Into<String>) -> Self {
39        Self::with_status(HTTP_INTERNAL_SERVER_ERROR, message)
40    }
41
42    pub fn not_found(message: impl Into<String>) -> Self {
43        Self::with_status(HTTP_NOT_FOUND, message)
44    }
45
46    pub fn unimplemented(message: impl Into<String>) -> Self {
47        Self::with_status(HTTP_NOT_IMPLEMENTED, message)
48    }
49
50    pub fn status(&self) -> Option<u16> {
51        self.status
52    }
53
54    pub fn message(&self) -> &str {
55        &self.message
56    }
57
58    pub(crate) fn expose_message(&self) -> bool {
59        self.expose_message
60    }
61
62    pub(crate) fn hidden_internal(message: impl Into<String>) -> Self {
63        Self {
64            status: Some(HTTP_INTERNAL_SERVER_ERROR),
65            message: message.into(),
66            expose_message: false,
67        }
68    }
69}
70
71impl From<serde_json::Error> for Error {
72    fn from(value: serde_json::Error) -> Self {
73        Self::hidden_internal(value.to_string())
74    }
75}
76
77impl From<std::io::Error> for Error {
78    fn from(value: std::io::Error) -> Self {
79        Self::hidden_internal(value.to_string())
80    }
81}
82
83impl From<tonic::transport::Error> for Error {
84    fn from(value: tonic::transport::Error) -> Self {
85        Self::hidden_internal(value.to_string())
86    }
87}