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