1use std::io;
7
8use thiserror::Error;
9
10pub type Result<T> = std::result::Result<T, Error>;
11
12#[derive(Debug, Error)]
14pub enum Error {
15 #[error("database error: {0}")]
16 Db(#[from] sqlx::Error),
17
18 #[error("database migration error: {0}")]
19 Migrate(#[from] sqlx::migrate::MigrateError),
20
21 #[error("io error: {0}")]
22 Io(#[from] io::Error),
23
24 #[error("json error: {0}")]
25 Json(#[from] serde_json::Error),
26
27 #[error("parse error: {0}")]
28 Parse(String),
29
30 #[error("mailbox not found: {0}")]
31 MailboxNotFound(String),
32
33 #[error("email not found: {0}")]
34 EmailNotFound(String),
35
36 #[error("attachment not found: {0}")]
37 AttachmentNotFound(String),
38
39 #[error("bounce rule not found: {0}")]
40 BounceRuleNotFound(String),
41
42 #[error("port {0} is already in use")]
43 PortInUse(u16),
44
45 #[error("port {0} not in allowed range")]
46 PortOutOfRange(u16),
47
48 #[error("ephemeral port range exhausted")]
49 PortRangeExhausted,
50
51 #[error("mailbox name '{0}' already exists in project")]
52 DuplicateMailbox(String),
53
54 #[error("smtp protocol error: {0}")]
55 SmtpProto(String),
56
57 #[error("invalid input: {0}")]
58 Invalid(String),
59
60 #[error("not implemented: {0}")]
61 NotImplemented(&'static str),
62
63 #[error("internal: {0}")]
64 Internal(String),
65}
66
67impl Error {
68 pub fn http_status(&self) -> http::StatusCode {
70 use http::StatusCode as S;
71 match self {
72 Error::MailboxNotFound(_)
73 | Error::EmailNotFound(_)
74 | Error::AttachmentNotFound(_)
75 | Error::BounceRuleNotFound(_) => S::NOT_FOUND,
76 Error::DuplicateMailbox(_) | Error::PortInUse(_) => S::CONFLICT,
77 Error::Invalid(_) | Error::Parse(_) | Error::PortOutOfRange(_) => S::BAD_REQUEST,
78 Error::NotImplemented(_) => S::NOT_IMPLEMENTED,
79 Error::PortRangeExhausted => S::SERVICE_UNAVAILABLE,
80 _ => S::INTERNAL_SERVER_ERROR,
81 }
82 }
83
84 pub fn code(&self) -> &'static str {
86 match self {
87 Error::Db(_) | Error::Migrate(_) => "db_error",
88 Error::Io(_) => "io_error",
89 Error::Json(_) => "json_error",
90 Error::Parse(_) => "parse_error",
91 Error::MailboxNotFound(_) => "mailbox_not_found",
92 Error::EmailNotFound(_) => "email_not_found",
93 Error::AttachmentNotFound(_) => "attachment_not_found",
94 Error::BounceRuleNotFound(_) => "bounce_rule_not_found",
95 Error::PortInUse(_) => "port_in_use",
96 Error::PortOutOfRange(_) => "port_out_of_range",
97 Error::PortRangeExhausted => "port_range_exhausted",
98 Error::DuplicateMailbox(_) => "duplicate_mailbox",
99 Error::SmtpProto(_) => "smtp_proto",
100 Error::Invalid(_) => "invalid_input",
101 Error::NotImplemented(_) => "not_implemented",
102 Error::Internal(_) => "internal",
103 }
104 }
105}