1use std::fmt::Display;
2
3#[cfg(feature = "serde")]
4#[macro_use]
5extern crate serde;
6
7#[cfg(feature = "schemas")]
8#[macro_use]
9extern crate schemars;
10
11#[cfg(feature = "utoipa")]
12#[macro_use]
13extern crate utoipa;
14
15#[cfg(feature = "rocket")]
16pub mod rocket;
17
18#[cfg(feature = "axum")]
19pub mod axum;
20
21#[cfg(feature = "okapi")]
22pub mod okapi;
23
24pub type Result<T, E = Error> = std::result::Result<T, E>;
26
27#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
29#[cfg_attr(feature = "schemas", derive(JsonSchema))]
30#[cfg_attr(feature = "utoipa", derive(ToSchema))]
31#[derive(Debug, Clone)]
32pub struct Error {
33 #[cfg_attr(feature = "serde", serde(flatten))]
35 pub error_type: ErrorType,
36
37 pub location: String,
39}
40
41impl Display for Error {
42 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43 write!(f, "{:?} occurred in {}", self.error_type, self.location)
44 }
45}
46
47impl std::error::Error for Error {}
48
49#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
51#[cfg_attr(feature = "serde", serde(tag = "type"))]
52#[cfg_attr(feature = "schemas", derive(JsonSchema))]
53#[cfg_attr(feature = "utoipa", derive(ToSchema))]
54#[derive(Debug, Clone)]
55pub enum ErrorType {
56 LabelMe,
58
59 AlreadyOnboarded,
61
62 UsernameTaken,
64 InvalidUsername,
65 DiscriminatorChangeRatelimited,
66 UnknownUser,
67 AlreadyFriends,
68 AlreadySentRequest,
69 Blocked,
70 BlockedByOther,
71 NotFriends,
72 TooManyPendingFriendRequests {
73 max: usize,
74 },
75
76 UnknownChannel,
78 UnknownAttachment,
79 UnknownMessage,
80 CannotEditMessage,
81 CannotJoinCall,
82 TooManyAttachments {
83 max: usize,
84 },
85 TooManyEmbeds {
86 max: usize,
87 },
88 TooManyReplies {
89 max: usize,
90 },
91 TooManyChannels {
92 max: usize,
93 },
94 EmptyMessage,
95 PayloadTooLarge,
96 CannotRemoveYourself,
97 GroupTooLarge {
98 max: usize,
99 },
100 AlreadyInGroup,
101 NotInGroup,
102 AlreadyPinned,
103 NotPinned,
104
105 UnknownServer,
107 InvalidRole,
108 Banned,
109 TooManyServers {
110 max: usize,
111 },
112 TooManyEmoji {
113 max: usize,
114 },
115 TooManyRoles {
116 max: usize,
117 },
118 AlreadyInServer,
119 CannotTimeoutYourself,
120
121 ReachedMaximumBots,
123 IsBot,
124 IsNotBot,
125 BotIsPrivate,
126
127 CannotReportYourself,
129
130 MissingPermission {
132 permission: String,
133 },
134 MissingUserPermission {
135 permission: String,
136 },
137 NotElevated,
138 NotPrivileged,
139 CannotGiveMissingPermissions,
140 NotOwner,
141
142 DatabaseError {
144 operation: String,
145 collection: String,
146 },
147 InternalError,
148 InvalidOperation,
149 InvalidCredentials,
150 InvalidProperty,
151 InvalidSession,
152 InvalidFlagValue,
153 NotAuthenticated,
154 DuplicateNonce,
155 NotFound,
156 NoEffect,
157 FailedValidation {
158 error: String,
159 },
160
161 ProxyError,
163 FileTooSmall,
164 FileTooLarge {
165 max: usize,
166 },
167 FileTypeNotAllowed,
168 ImageProcessingFailed,
169 NoEmbedData,
170
171 VosoUnavailable,
173
174 FeatureDisabled {
176 feature: String,
177 },
178}
179
180#[macro_export]
181macro_rules! create_error {
182 ( $error: ident $( $tt:tt )? ) => {
183 $crate::Error {
184 error_type: $crate::ErrorType::$error $( $tt )?,
185 location: format!("{}:{}:{}", file!(), line!(), column!()),
186 }
187 };
188}
189
190#[macro_export]
191macro_rules! create_database_error {
192 ( $operation: expr, $collection: expr ) => {
193 $crate::create_error!(DatabaseError {
194 operation: $operation.to_string(),
195 collection: $collection.to_string()
196 })
197 };
198}
199
200#[cfg(test)]
201mod tests {
202 use crate::ErrorType;
203
204 #[test]
205 fn use_macro_to_construct_error() {
206 let error = create_error!(LabelMe);
207 assert!(matches!(error.error_type, ErrorType::LabelMe));
208 }
209
210 #[test]
211 fn use_macro_to_construct_complex_error() {
212 let error = create_error!(LabelMe);
213 assert!(matches!(error.error_type, ErrorType::LabelMe));
214 }
215}