1use anyhow::Error as AnyhowError;
2use thiserror::*;
3
4#[derive(Debug, Error)]
6pub enum ServerError {
7 #[error("forbidden request: {0}")]
9 Forbidden(String),
10
11 #[error("not found")]
13 NotFound,
14
15 #[error(transparent)]
17 Domain(#[from] crate::domain::DomainError),
18
19 #[error("internal server error: {0}")]
22 Internal(
23 #[from]
24 #[source]
25 AnyhowError,
26 ),
27}
28
29macro_rules! bug_inner {
30 ($msg:expr) => {{
31 let location = std::panic::Location::caller();
32 let message = format!("BUG at {}:{}:{} - {}",
33 location.file(), location.line(), location.column(), $msg);
34
35 #[cfg(feature = "backtrace")]
36 {
37 let backtrace = std::backtrace::Backtrace::capture();
38 if backtrace.status() == std::backtrace::BacktraceStatus::Captured {
39 use std::fmt::Write;
40 let _ = writeln!(message.clone(), "\n\nBacktrace:\n{backtrace:?}");
41 }
42 }
43
44 ServerError::Internal(anyhow::anyhow!(message))
45 }};
46 ($fmt:expr, $($arg:tt)*) => { bug_inner!(format_args!($fmt, $($arg)*)) };
47}
48
49macro_rules! bug {
50 () => {
51 |error| $crate::error::bug_inner!(error)
52 };
53
54 ($($msg:tt)*) => {{
55 |e| $crate::error::bug_inner!(format_args!("{}: {}", format_args!($($msg)*), e))
56 }};
57}
58
59pub(crate) use bug;
60pub(crate) use bug_inner;