ruma_common/api/error/kind.rs
1use std::str::FromStr;
2
3use as_variant::as_variant;
4use ruma_common::{
5 RoomVersionId,
6 api::error::{HeaderDeserializationError, HeaderSerializationError},
7 http_headers::{http_date_to_system_time, system_time_to_http_date},
8 serde::{JsonObject, StringEnum},
9};
10use web_time::{Duration, SystemTime};
11
12use crate::PrivOwnedStr;
13
14/// An enum for the error kind.
15///
16/// Items may contain additional information.
17#[derive(Clone, Debug, PartialEq, Eq)]
18#[non_exhaustive]
19// Please keep the variants sorted alphabetically.
20pub enum ErrorKind {
21 /// `M_APPSERVICE_LOGIN_UNSUPPORTED`
22 ///
23 /// An application service used the [`m.login.application_service`] type an endpoint from the
24 /// [legacy authentication API] in a way that is not supported by the homeserver, because the
25 /// server only supports the [OAuth 2.0 API].
26 ///
27 /// [`m.login.application_service`]: https://spec.matrix.org/v1.18/application-service-api/#server-admin-style-permissions
28 /// [legacy authentication API]: https://spec.matrix.org/v1.18/client-server-api/#legacy-api
29 /// [OAuth 2.0 API]: https://spec.matrix.org/v1.18/client-server-api/#oauth-20-api
30 AppserviceLoginUnsupported,
31
32 /// `M_BAD_ALIAS`
33 ///
34 /// One or more [room aliases] within the `m.room.canonical_alias` event do not point to the
35 /// room ID for which the state event is to be sent to.
36 ///
37 /// [room aliases]: https://spec.matrix.org/v1.18/client-server-api/#room-aliases
38 BadAlias,
39
40 /// `M_BAD_JSON`
41 ///
42 /// The request contained valid JSON, but it was malformed in some way, e.g. missing required
43 /// keys, invalid values for keys.
44 BadJson,
45
46 /// `M_BAD_STATE`
47 ///
48 /// The state change requested cannot be performed, such as attempting to unban a user who is
49 /// not banned.
50 BadState,
51
52 /// `M_BAD_STATUS`
53 ///
54 /// The application service returned a bad status.
55 BadStatus(BadStatusErrorData),
56
57 /// `M_CANNOT_LEAVE_SERVER_NOTICE_ROOM`
58 ///
59 /// The user is unable to reject an invite to join the [server notices] room.
60 ///
61 /// [server notices]: https://spec.matrix.org/v1.18/client-server-api/#server-notices
62 CannotLeaveServerNoticeRoom,
63
64 /// `M_CANNOT_OVERWRITE_MEDIA`
65 ///
66 /// The `PUT /_matrix/media/*/upload/{serverName}/{mediaId}` endpoint was called with a media ID
67 /// that already has content.
68 CannotOverwriteMedia,
69
70 /// `M_CAPTCHA_INVALID`
71 ///
72 /// The Captcha provided did not match what was expected.
73 CaptchaInvalid,
74
75 /// `M_CAPTCHA_NEEDED`
76 ///
77 /// A Captcha is required to complete the request.
78 CaptchaNeeded,
79
80 /// `M_CONFLICTING_UNSUBSCRIPTION`
81 ///
82 /// Part of [MSC4306]: an automatic thread subscription has been skipped by the server, because
83 /// the user unsubsubscribed after the indicated subscribed-to event.
84 ///
85 /// [MSC4306]: https://github.com/matrix-org/matrix-spec-proposals/pull/4306
86 #[cfg(feature = "unstable-msc4306")]
87 ConflictingUnsubscription,
88
89 /// `M_CONNECTION_FAILED`
90 ///
91 /// The connection to the application service failed.
92 ConnectionFailed,
93
94 /// `M_CONNECTION_TIMEOUT`
95 ///
96 /// The connection to the application service timed out.
97 ConnectionTimeout,
98
99 /// `M_DUPLICATE_ANNOTATION`
100 ///
101 /// The request is an attempt to send a [duplicate annotation].
102 ///
103 /// [duplicate annotation]: https://spec.matrix.org/v1.18/client-server-api/#avoiding-duplicate-annotations
104 DuplicateAnnotation,
105
106 /// `M_EXCLUSIVE`
107 ///
108 /// The resource being requested is reserved by an application service, or the application
109 /// service making the request has not created the resource.
110 Exclusive,
111
112 /// `M_FORBIDDEN`
113 ///
114 /// Forbidden access, e.g. joining a room without permission, failed login.
115 Forbidden,
116
117 /// `M_GUEST_ACCESS_FORBIDDEN`
118 ///
119 /// The room or resource does not permit [guests] to access it.
120 ///
121 /// [guests]: https://spec.matrix.org/v1.18/client-server-api/#guest-access
122 GuestAccessForbidden,
123
124 /// `M_INCOMPATIBLE_ROOM_VERSION`
125 ///
126 /// The client attempted to join a room that has a version the server does not support.
127 IncompatibleRoomVersion(IncompatibleRoomVersionErrorData),
128
129 /// `M_INVALID_PARAM`
130 ///
131 /// A parameter that was specified has the wrong value. For example, the server expected an
132 /// integer and instead received a string.
133 InvalidParam,
134
135 /// `M_INVALID_ROOM_STATE`
136 ///
137 /// The initial state implied by the parameters to the `POST /_matrix/client/*/createRoom`
138 /// request is invalid, e.g. the user's `power_level` is set below that necessary to set the
139 /// room name.
140 InvalidRoomState,
141
142 /// `M_INVALID_USERNAME`
143 ///
144 /// The desired user name is not valid.
145 InvalidUsername,
146
147 /// `M_INVITE_BLOCKED`
148 ///
149 /// The invite was interdicted by moderation tools or configured access controls without having
150 /// been witnessed by the invitee.
151 InviteBlocked,
152
153 /// `M_LIMIT_EXCEEDED`
154 ///
155 /// The request has been refused due to [rate limiting]: too many requests have been sent in a
156 /// short period of time.
157 ///
158 /// [rate limiting]: https://spec.matrix.org/v1.18/client-server-api/#rate-limiting
159 LimitExceeded(LimitExceededErrorData),
160
161 /// `M_MISSING_PARAM`
162 ///
163 /// A required parameter was missing from the request.
164 MissingParam,
165
166 /// `M_MISSING_TOKEN`
167 ///
168 /// No [access token] was specified for the request, but one is required.
169 ///
170 /// [access token]: https://spec.matrix.org/v1.18/client-server-api/#client-authentication
171 MissingToken,
172
173 /// `M_NOT_FOUND`
174 ///
175 /// No resource was found for this request.
176 NotFound,
177
178 /// `M_NOT_IN_THREAD`
179 ///
180 /// Part of [MSC4306]: an automatic thread subscription was set to an event ID that isn't part
181 /// of the subscribed-to thread.
182 ///
183 /// [MSC4306]: https://github.com/matrix-org/matrix-spec-proposals/pull/4306
184 #[cfg(feature = "unstable-msc4306")]
185 NotInThread,
186
187 /// `M_NOT_JSON`
188 ///
189 /// The request did not contain valid JSON.
190 NotJson,
191
192 /// `M_NOT_YET_UPLOADED`
193 ///
194 /// An `mxc:` URI generated with the `POST /_matrix/media/*/create` endpoint was used and the
195 /// content is not yet available.
196 NotYetUploaded,
197
198 /// `M_RESOURCE_LIMIT_EXCEEDED`
199 ///
200 /// The request cannot be completed because the homeserver has reached a resource limit imposed
201 /// on it. For example, a homeserver held in a shared hosting environment may reach a resource
202 /// limit if it starts using too much memory or disk space.
203 ResourceLimitExceeded(ResourceLimitExceededErrorData),
204
205 /// `M_ROOM_IN_USE`
206 ///
207 /// The [room alias] specified in the `POST /_matrix/client/*/createRoom` request is already
208 /// taken.
209 ///
210 /// [room alias]: https://spec.matrix.org/v1.18/client-server-api/#room-aliases
211 RoomInUse,
212
213 /// `M_SERVER_NOT_TRUSTED`
214 ///
215 /// The client's request used a third-party server, e.g. identity server, that this server does
216 /// not trust.
217 ServerNotTrusted,
218
219 /// `M_THREEPID_AUTH_FAILED`
220 ///
221 /// Authentication could not be performed on the [third-party identifier].
222 ///
223 /// [third-party identifier]: https://spec.matrix.org/v1.18/client-server-api/#adding-account-administrative-contact-information
224 ThreepidAuthFailed,
225
226 /// `M_THREEPID_DENIED`
227 ///
228 /// The server does not permit this [third-party identifier]. This may happen if the server
229 /// only permits, for example, email addresses from a particular domain.
230 ///
231 /// [third-party identifier]: https://spec.matrix.org/v1.18/client-server-api/#adding-account-administrative-contact-information
232 ThreepidDenied,
233
234 /// `M_THREEPID_IN_USE`
235 ///
236 /// The [third-party identifier] is already in use by another user.
237 ///
238 /// [third-party identifier]: https://spec.matrix.org/v1.18/client-server-api/#adding-account-administrative-contact-information
239 ThreepidInUse,
240
241 /// `M_THREEPID_MEDIUM_NOT_SUPPORTED`
242 ///
243 /// The homeserver does not support adding a [third-party identifier] of the given medium.
244 ///
245 /// [third-party identifier]: https://spec.matrix.org/v1.18/client-server-api/#adding-account-administrative-contact-information
246 ThreepidMediumNotSupported,
247
248 /// `M_THREEPID_NOT_FOUND`
249 ///
250 /// No account matching the given [third-party identifier] could be found.
251 ///
252 /// [third-party identifier]: https://spec.matrix.org/v1.18/client-server-api/#adding-account-administrative-contact-information
253 ThreepidNotFound,
254
255 /// `M_TOKEN_INCORRECT`
256 ///
257 /// The token that the user entered to validate the session is incorrect.
258 TokenIncorrect,
259
260 /// `M_TOO_LARGE`
261 ///
262 /// The request or entity was too large.
263 TooLarge,
264
265 /// `M_UNABLE_TO_AUTHORISE_JOIN`
266 ///
267 /// The room is [restricted] and none of the conditions can be validated by the homeserver.
268 /// This can happen if the homeserver does not know about any of the rooms listed as
269 /// conditions, for example.
270 ///
271 /// [restricted]: https://spec.matrix.org/v1.18/client-server-api/#restricted-rooms
272 UnableToAuthorizeJoin,
273
274 /// `M_UNABLE_TO_GRANT_JOIN`
275 ///
276 /// A different server should be attempted for the join. This is typically because the resident
277 /// server can see that the joining user satisfies one or more conditions, such as in the case
278 /// of [restricted rooms], but the resident server would be unable to meet the authorization
279 /// rules.
280 ///
281 /// [restricted rooms]: https://spec.matrix.org/v1.18/client-server-api/#restricted-rooms
282 UnableToGrantJoin,
283
284 /// `M_UNACTIONABLE`
285 ///
286 /// The server does not want to handle the [federated report].
287 ///
288 /// [federated report]: https://github.com/matrix-org/matrix-spec-proposals/pull/3843
289 #[cfg(feature = "unstable-msc3843")]
290 Unactionable,
291
292 /// `M_UNAUTHORIZED`
293 ///
294 /// The request was not correctly authorized. Usually due to login failures.
295 Unauthorized,
296
297 /// `M_UNKNOWN`
298 ///
299 /// An unknown error has occurred.
300 Unknown,
301
302 /// `M_UNKNOWN_POS`
303 ///
304 /// The sliding sync ([MSC4186]) connection was expired by the server.
305 ///
306 /// [MSC4186]: https://github.com/matrix-org/matrix-spec-proposals/pull/4186
307 #[cfg(feature = "unstable-msc4186")]
308 UnknownPos,
309
310 /// `M_UNKNOWN_TOKEN`
311 ///
312 /// The [access or refresh token] specified was not recognized.
313 ///
314 /// [access or refresh token]: https://spec.matrix.org/v1.18/client-server-api/#client-authentication
315 UnknownToken(UnknownTokenErrorData),
316
317 /// `M_UNRECOGNIZED`
318 ///
319 /// The server did not understand the request.
320 ///
321 /// This is expected to be returned with a 404 HTTP status code if the endpoint is not
322 /// implemented or a 405 HTTP status code if the endpoint is implemented, but the incorrect
323 /// HTTP method is used.
324 Unrecognized,
325
326 /// `M_UNSUPPORTED_ROOM_VERSION`
327 ///
328 /// The request to `POST /_matrix/client/*/createRoom` used a room version that the server does
329 /// not support.
330 UnsupportedRoomVersion,
331
332 /// `M_URL_NOT_SET`
333 ///
334 /// The application service doesn't have a URL configured.
335 UrlNotSet,
336
337 /// `M_USER_DEACTIVATED`
338 ///
339 /// The user ID associated with the request has been deactivated.
340 UserDeactivated,
341
342 /// `M_USER_IN_USE`
343 ///
344 /// The desired user ID is already taken.
345 UserInUse,
346
347 /// `M_USER_LIMIT_EXCEEDED`
348 ///
349 /// The request cannot be completed because the user has exceeded (or the request would cause
350 /// them to exceed) a limit associated with their account. For example, a user may have reached
351 /// their allocated storage quota, reached a maximum number of allowed rooms, devices, or other
352 /// account-scoped resources, or exceeded usage limits for specific features.
353 UserLimitExceeded(UserLimitExceededErrorData),
354
355 /// `M_USER_LOCKED`
356 ///
357 /// The account has been [locked] and cannot be used at this time.
358 ///
359 /// [locked]: https://spec.matrix.org/v1.18/client-server-api/#account-locking
360 UserLocked,
361
362 /// `M_USER_SUSPENDED`
363 ///
364 /// The account has been [suspended] and can only be used for limited actions at this time.
365 ///
366 /// [suspended]: https://spec.matrix.org/v1.18/client-server-api/#account-suspension
367 UserSuspended,
368
369 /// `M_WEAK_PASSWORD`
370 ///
371 /// The password was [rejected] by the server for being too weak.
372 ///
373 /// [rejected]: https://spec.matrix.org/v1.18/client-server-api/#password-management
374 WeakPassword,
375
376 /// `M_WRONG_ROOM_KEYS_VERSION`
377 ///
378 /// The version of the [room keys backup] provided in the request does not match the current
379 /// backup version.
380 ///
381 /// [room keys backup]: https://spec.matrix.org/v1.18/client-server-api/#server-side-key-backups
382 WrongRoomKeysVersion(WrongRoomKeysVersionErrorData),
383
384 #[doc(hidden)]
385 _Custom(CustomErrorKind),
386}
387
388impl ErrorKind {
389 /// Get the [`ErrorCode`] for this `ErrorKind`.
390 pub fn errcode(&self) -> ErrorCode {
391 match self {
392 ErrorKind::AppserviceLoginUnsupported => ErrorCode::AppserviceLoginUnsupported,
393 ErrorKind::BadAlias => ErrorCode::BadAlias,
394 ErrorKind::BadJson => ErrorCode::BadJson,
395 ErrorKind::BadState => ErrorCode::BadState,
396 ErrorKind::BadStatus(_) => ErrorCode::BadStatus,
397 ErrorKind::CannotLeaveServerNoticeRoom => ErrorCode::CannotLeaveServerNoticeRoom,
398 ErrorKind::CannotOverwriteMedia => ErrorCode::CannotOverwriteMedia,
399 ErrorKind::CaptchaInvalid => ErrorCode::CaptchaInvalid,
400 ErrorKind::CaptchaNeeded => ErrorCode::CaptchaNeeded,
401 #[cfg(feature = "unstable-msc4306")]
402 ErrorKind::ConflictingUnsubscription => ErrorCode::ConflictingUnsubscription,
403 ErrorKind::ConnectionFailed => ErrorCode::ConnectionFailed,
404 ErrorKind::ConnectionTimeout => ErrorCode::ConnectionTimeout,
405 ErrorKind::DuplicateAnnotation => ErrorCode::DuplicateAnnotation,
406 ErrorKind::Exclusive => ErrorCode::Exclusive,
407 ErrorKind::Forbidden => ErrorCode::Forbidden,
408 ErrorKind::GuestAccessForbidden => ErrorCode::GuestAccessForbidden,
409 ErrorKind::IncompatibleRoomVersion(_) => ErrorCode::IncompatibleRoomVersion,
410 ErrorKind::InvalidParam => ErrorCode::InvalidParam,
411 ErrorKind::InvalidRoomState => ErrorCode::InvalidRoomState,
412 ErrorKind::InvalidUsername => ErrorCode::InvalidUsername,
413 ErrorKind::InviteBlocked => ErrorCode::InviteBlocked,
414 ErrorKind::LimitExceeded(_) => ErrorCode::LimitExceeded,
415 ErrorKind::MissingParam => ErrorCode::MissingParam,
416 ErrorKind::MissingToken => ErrorCode::MissingToken,
417 ErrorKind::NotFound => ErrorCode::NotFound,
418 #[cfg(feature = "unstable-msc4306")]
419 ErrorKind::NotInThread => ErrorCode::NotInThread,
420 ErrorKind::NotJson => ErrorCode::NotJson,
421 ErrorKind::NotYetUploaded => ErrorCode::NotYetUploaded,
422 ErrorKind::ResourceLimitExceeded(_) => ErrorCode::ResourceLimitExceeded,
423 ErrorKind::RoomInUse => ErrorCode::RoomInUse,
424 ErrorKind::ServerNotTrusted => ErrorCode::ServerNotTrusted,
425 ErrorKind::ThreepidAuthFailed => ErrorCode::ThreepidAuthFailed,
426 ErrorKind::ThreepidDenied => ErrorCode::ThreepidDenied,
427 ErrorKind::ThreepidInUse => ErrorCode::ThreepidInUse,
428 ErrorKind::ThreepidMediumNotSupported => ErrorCode::ThreepidMediumNotSupported,
429 ErrorKind::ThreepidNotFound => ErrorCode::ThreepidNotFound,
430 ErrorKind::TokenIncorrect => ErrorCode::TokenIncorrect,
431 ErrorKind::TooLarge => ErrorCode::TooLarge,
432 ErrorKind::UnableToAuthorizeJoin => ErrorCode::UnableToAuthorizeJoin,
433 ErrorKind::UnableToGrantJoin => ErrorCode::UnableToGrantJoin,
434 #[cfg(feature = "unstable-msc3843")]
435 ErrorKind::Unactionable => ErrorCode::Unactionable,
436 ErrorKind::Unauthorized => ErrorCode::Unauthorized,
437 ErrorKind::Unknown => ErrorCode::Unknown,
438 #[cfg(feature = "unstable-msc4186")]
439 ErrorKind::UnknownPos => ErrorCode::UnknownPos,
440 ErrorKind::UnknownToken(_) => ErrorCode::UnknownToken,
441 ErrorKind::Unrecognized => ErrorCode::Unrecognized,
442 ErrorKind::UnsupportedRoomVersion => ErrorCode::UnsupportedRoomVersion,
443 ErrorKind::UrlNotSet => ErrorCode::UrlNotSet,
444 ErrorKind::UserDeactivated => ErrorCode::UserDeactivated,
445 ErrorKind::UserInUse => ErrorCode::UserInUse,
446 ErrorKind::UserLimitExceeded(_) => ErrorCode::UserLimitExceeded,
447 ErrorKind::UserLocked => ErrorCode::UserLocked,
448 ErrorKind::UserSuspended => ErrorCode::UserSuspended,
449 ErrorKind::WeakPassword => ErrorCode::WeakPassword,
450 ErrorKind::WrongRoomKeysVersion(_) => ErrorCode::WrongRoomKeysVersion,
451 ErrorKind::_Custom(CustomErrorKind { errcode, .. }) => errcode.as_str().into(),
452 }
453 }
454
455 /// Get the JSON data for this `ErrorKind`, if it uses a custom error code.
456 pub fn custom_json_data(&self) -> Option<&JsonObject> {
457 as_variant!(self, Self::_Custom(error_kind) => &error_kind.data)
458 }
459}
460
461/// Data for the `M_BAD_STATUS` [`ErrorKind`].
462#[derive(Clone, Debug, Default, PartialEq, Eq)]
463#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
464pub struct BadStatusErrorData {
465 /// The HTTP status code of the response.
466 pub status: Option<http::StatusCode>,
467
468 /// The body of the response.
469 pub body: Option<String>,
470}
471
472impl BadStatusErrorData {
473 /// Construct a new empty `BadStatusErrorData`.
474 pub fn new() -> Self {
475 Self::default()
476 }
477}
478
479/// Data for the `M_INCOMPATIBLE_ROOM_VERSION` [`ErrorKind`].
480#[derive(Clone, Debug, PartialEq, Eq)]
481#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
482pub struct IncompatibleRoomVersionErrorData {
483 /// The room's version.
484 pub room_version: RoomVersionId,
485}
486
487impl IncompatibleRoomVersionErrorData {
488 /// Construct a new `IncompatibleRoomVersionErrorData` with the given room version.
489 pub fn new(room_version: RoomVersionId) -> Self {
490 Self { room_version }
491 }
492}
493
494/// Data for the `M_LIMIT_EXCEEDED` [`ErrorKind`].
495#[derive(Clone, Debug, Default, PartialEq, Eq)]
496#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
497pub struct LimitExceededErrorData {
498 /// How long a client should wait before they can try again.
499 pub retry_after: Option<RetryAfter>,
500}
501
502impl LimitExceededErrorData {
503 /// Construct a new empty `LimitExceededErrorData`.
504 pub fn new() -> Self {
505 Self::default()
506 }
507}
508
509/// How long a client should wait before it tries again.
510#[derive(Debug, Clone, Copy, PartialEq, Eq)]
511#[allow(clippy::exhaustive_enums)]
512pub enum RetryAfter {
513 /// The client should wait for the given duration.
514 ///
515 /// This variant should be preferred for backwards compatibility, as it will also populate the
516 /// `retry_after_ms` field in the body of the response.
517 Delay(Duration),
518 /// The client should wait for the given date and time.
519 DateTime(SystemTime),
520}
521
522impl TryFrom<&http::HeaderValue> for RetryAfter {
523 type Error = HeaderDeserializationError;
524
525 fn try_from(value: &http::HeaderValue) -> Result<Self, Self::Error> {
526 if value.as_bytes().iter().all(|b| b.is_ascii_digit()) {
527 // It should be a duration.
528 Ok(Self::Delay(Duration::from_secs(u64::from_str(value.to_str()?)?)))
529 } else {
530 // It should be a date.
531 Ok(Self::DateTime(http_date_to_system_time(value)?))
532 }
533 }
534}
535
536impl TryFrom<&RetryAfter> for http::HeaderValue {
537 type Error = HeaderSerializationError;
538
539 fn try_from(value: &RetryAfter) -> Result<Self, Self::Error> {
540 match value {
541 RetryAfter::Delay(duration) => Ok(duration.as_secs().into()),
542 RetryAfter::DateTime(time) => system_time_to_http_date(time),
543 }
544 }
545}
546
547/// Data for the `M_RESOURCE_LIMIT_EXCEEDED` [`ErrorKind`].
548#[derive(Clone, Debug, PartialEq, Eq)]
549#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
550pub struct ResourceLimitExceededErrorData {
551 /// A URI giving a contact method for the server administrator.
552 pub admin_contact: String,
553}
554
555impl ResourceLimitExceededErrorData {
556 /// Construct a new `ResourceLimitExceededErrorData` with the given admin contact URI.
557 pub fn new(admin_contact: String) -> Self {
558 Self { admin_contact }
559 }
560}
561
562/// Data for the `M_UNKNOWN_TOKEN` [`ErrorKind`].
563#[derive(Clone, Debug, Default, PartialEq, Eq)]
564#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
565pub struct UnknownTokenErrorData {
566 /// If this is `true`, the client is in a "[soft logout]" state, i.e. the server requires
567 /// re-authentication but the session is not invalidated. The client can acquire a new
568 /// access token by specifying the device ID it is already using to the login API.
569 ///
570 /// [soft logout]: https://spec.matrix.org/v1.18/client-server-api/#soft-logout
571 pub soft_logout: bool,
572}
573
574impl UnknownTokenErrorData {
575 /// Construct a new `UnknownTokenErrorData` with `soft_logout` set to `false`.
576 pub fn new() -> Self {
577 Self::default()
578 }
579}
580
581/// Data for the `M_USER_LIMIT_EXCEEDED` [`ErrorKind`].
582#[derive(Clone, Debug, PartialEq, Eq)]
583#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
584pub struct UserLimitExceededErrorData {
585 /// A URI that the client can present to the user to provide more context on the encountered
586 /// limit and, if applicable, guidance on how to increase the limit.
587 ///
588 /// The homeserver MAY return different values depending on the type of limit reached.
589 pub info_uri: String,
590
591 /// Whether the specific limit encountered can be increased.
592 ///
593 /// If `true`, it indicates that the specific limit encountered can be increased, for example
594 /// by upgrading the user’s account tier. If `false`, the limit is a hard limit that cannot be
595 /// increased.
596 ///
597 /// Defaults to `false`.
598 pub can_upgrade: bool,
599}
600
601impl UserLimitExceededErrorData {
602 /// Construct a new `UserLimitExceededErrorData` with the given URI.
603 pub fn new(info_uri: String) -> Self {
604 Self { info_uri, can_upgrade: false }
605 }
606}
607
608/// Data for the `M_WRONG_ROOM_KEYS_VERSION` [`ErrorKind`].
609#[derive(Clone, Debug, PartialEq, Eq)]
610#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
611pub struct WrongRoomKeysVersionErrorData {
612 /// The currently active backup version.
613 pub current_version: String,
614}
615
616impl WrongRoomKeysVersionErrorData {
617 /// Construct a new `WrongRoomKeysVersionErrorData` with the given current active backup
618 /// version.
619 pub fn new(current_version: String) -> Self {
620 Self { current_version }
621 }
622}
623
624/// A custom error kind.
625#[doc(hidden)]
626#[derive(Clone, Debug, PartialEq, Eq)]
627pub struct CustomErrorKind {
628 /// The error code.
629 pub(super) errcode: String,
630
631 /// The data for the error.
632 pub(super) data: JsonObject,
633}
634
635/// The possible [error codes] defined in the Matrix spec.
636///
637/// [error codes]: https://spec.matrix.org/v1.18/client-server-api/#standard-error-response
638#[derive(Clone, StringEnum)]
639#[non_exhaustive]
640#[ruma_enum(rename_all(prefix = "M_", rule = "SCREAMING_SNAKE_CASE"))]
641// Please keep the variants sorted alphabetically.
642pub enum ErrorCode {
643 /// `M_APPSERVICE_LOGIN_UNSUPPORTED`
644 ///
645 /// An application service used the [`m.login.application_service`] type an endpoint from the
646 /// [legacy authentication API] in a way that is not supported by the homeserver, because the
647 /// server only supports the [OAuth 2.0 API].
648 ///
649 /// [`m.login.application_service`]: https://spec.matrix.org/v1.18/application-service-api/#server-admin-style-permissions
650 /// [legacy authentication API]: https://spec.matrix.org/v1.18/client-server-api/#legacy-api
651 /// [OAuth 2.0 API]: https://spec.matrix.org/v1.18/client-server-api/#oauth-20-api
652 AppserviceLoginUnsupported,
653
654 /// `M_BAD_ALIAS`
655 ///
656 /// One or more [room aliases] within the `m.room.canonical_alias` event do not point to the
657 /// room ID for which the state event is to be sent to.
658 ///
659 /// [room aliases]: https://spec.matrix.org/v1.18/client-server-api/#room-aliases
660 BadAlias,
661
662 /// `M_BAD_JSON`
663 ///
664 /// The request contained valid JSON, but it was malformed in some way, e.g. missing required
665 /// keys, invalid values for keys.
666 BadJson,
667
668 /// `M_BAD_STATE`
669 ///
670 /// The state change requested cannot be performed, such as attempting to unban a user who is
671 /// not banned.
672 BadState,
673
674 /// `M_BAD_STATUS`
675 ///
676 /// The application service returned a bad status.
677 BadStatus,
678
679 /// `M_CANNOT_LEAVE_SERVER_NOTICE_ROOM`
680 ///
681 /// The user is unable to reject an invite to join the [server notices] room.
682 ///
683 /// [server notices]: https://spec.matrix.org/v1.18/client-server-api/#server-notices
684 CannotLeaveServerNoticeRoom,
685
686 /// `M_CANNOT_OVERWRITE_MEDIA`
687 ///
688 /// The `PUT /_matrix/media/*/upload/{serverName}/{mediaId}` endpoint was called with a media ID
689 /// that already has content.
690 CannotOverwriteMedia,
691
692 /// `M_CAPTCHA_INVALID`
693 ///
694 /// The Captcha provided did not match what was expected.
695 CaptchaInvalid,
696
697 /// `M_CAPTCHA_NEEDED`
698 ///
699 /// A Captcha is required to complete the request.
700 CaptchaNeeded,
701
702 /// `M_CONFLICTING_UNSUBSCRIPTION`
703 ///
704 /// Part of [MSC4306]: an automatic thread subscription has been skipped by the server, because
705 /// the user unsubsubscribed after the indicated subscribed-to event.
706 ///
707 /// [MSC4306]: https://github.com/matrix-org/matrix-spec-proposals/pull/4306
708 #[cfg(feature = "unstable-msc4306")]
709 #[ruma_enum(rename = "IO.ELEMENT.MSC4306.M_CONFLICTING_UNSUBSCRIPTION")]
710 ConflictingUnsubscription,
711
712 /// `M_CONNECTION_FAILED`
713 ///
714 /// The connection to the application service failed.
715 ConnectionFailed,
716
717 /// `M_CONNECTION_TIMEOUT`
718 ///
719 /// The connection to the application service timed out.
720 ConnectionTimeout,
721
722 /// `M_DUPLICATE_ANNOTATION`
723 ///
724 /// The request is an attempt to send a [duplicate annotation].
725 ///
726 /// [duplicate annotation]: https://spec.matrix.org/v1.18/client-server-api/#avoiding-duplicate-annotations
727 DuplicateAnnotation,
728
729 /// `M_EXCLUSIVE`
730 ///
731 /// The resource being requested is reserved by an application service, or the application
732 /// service making the request has not created the resource.
733 Exclusive,
734
735 /// `M_FORBIDDEN`
736 ///
737 /// Forbidden access, e.g. joining a room without permission, failed login.
738 Forbidden,
739
740 /// `M_GUEST_ACCESS_FORBIDDEN`
741 ///
742 /// The room or resource does not permit [guests] to access it.
743 ///
744 /// [guests]: https://spec.matrix.org/v1.18/client-server-api/#guest-access
745 GuestAccessForbidden,
746
747 /// `M_INCOMPATIBLE_ROOM_VERSION`
748 ///
749 /// The client attempted to join a room that has a version the server does not support.
750 IncompatibleRoomVersion,
751
752 /// `M_INVALID_PARAM`
753 ///
754 /// A parameter that was specified has the wrong value. For example, the server expected an
755 /// integer and instead received a string.
756 InvalidParam,
757
758 /// `M_INVALID_ROOM_STATE`
759 ///
760 /// The initial state implied by the parameters to the `POST /_matrix/client/*/createRoom`
761 /// request is invalid, e.g. the user's `power_level` is set below that necessary to set the
762 /// room name.
763 InvalidRoomState,
764
765 /// `M_INVALID_USERNAME`
766 ///
767 /// The desired user name is not valid.
768 InvalidUsername,
769
770 /// `M_INVITE_BLOCKED`
771 ///
772 /// The invite was interdicted by moderation tools or configured access controls without having
773 /// been witnessed by the invitee.
774 ///
775 /// Unstable prefix intentionally shared with MSC4155 for compatibility.
776 #[ruma_enum(alias = "ORG.MATRIX.MSC4155.INVITE_BLOCKED")]
777 InviteBlocked,
778
779 /// `M_LIMIT_EXCEEDED`
780 ///
781 /// The request has been refused due to [rate limiting]: too many requests have been sent in a
782 /// short period of time.
783 ///
784 /// [rate limiting]: https://spec.matrix.org/v1.18/client-server-api/#rate-limiting
785 LimitExceeded,
786
787 /// `M_MISSING_PARAM`
788 ///
789 /// A required parameter was missing from the request.
790 MissingParam,
791
792 /// `M_MISSING_TOKEN`
793 ///
794 /// No [access token] was specified for the request, but one is required.
795 ///
796 /// [access token]: https://spec.matrix.org/v1.18/client-server-api/#client-authentication
797 MissingToken,
798
799 /// `M_NOT_FOUND`
800 ///
801 /// No resource was found for this request.
802 NotFound,
803
804 /// `M_NOT_IN_THREAD`
805 ///
806 /// Part of [MSC4306]: an automatic thread subscription was set to an event ID that isn't part
807 /// of the subscribed-to thread.
808 ///
809 /// [MSC4306]: https://github.com/matrix-org/matrix-spec-proposals/pull/4306
810 #[cfg(feature = "unstable-msc4306")]
811 #[ruma_enum(rename = "IO.ELEMENT.MSC4306.M_NOT_IN_THREAD")]
812 NotInThread,
813
814 /// `M_NOT_JSON`
815 ///
816 /// The request did not contain valid JSON.
817 NotJson,
818
819 /// `M_NOT_YET_UPLOADED`
820 ///
821 /// An `mxc:` URI generated with the `POST /_matrix/media/*/create` endpoint was used and the
822 /// content is not yet available.
823 NotYetUploaded,
824
825 /// `M_RESOURCE_LIMIT_EXCEEDED`
826 ///
827 /// The request cannot be completed because the homeserver has reached a resource limit imposed
828 /// on it. For example, a homeserver held in a shared hosting environment may reach a resource
829 /// limit if it starts using too much memory or disk space.
830 ResourceLimitExceeded,
831
832 /// `M_ROOM_IN_USE`
833 ///
834 /// The [room alias] specified in the `POST /_matrix/client/*/createRoom` request is already
835 /// taken.
836 ///
837 /// [room alias]: https://spec.matrix.org/v1.18/client-server-api/#room-aliases
838 RoomInUse,
839
840 /// `M_SERVER_NOT_TRUSTED`
841 ///
842 /// The client's request used a third-party server, e.g. identity server, that this server does
843 /// not trust.
844 ServerNotTrusted,
845
846 /// `M_THREEPID_AUTH_FAILED`
847 ///
848 /// Authentication could not be performed on the [third-party identifier].
849 ///
850 /// [third-party identifier]: https://spec.matrix.org/v1.18/client-server-api/#adding-account-administrative-contact-information
851 ThreepidAuthFailed,
852
853 /// `M_THREEPID_DENIED`
854 ///
855 /// The server does not permit this [third-party identifier]. This may happen if the server
856 /// only permits, for example, email addresses from a particular domain.
857 ///
858 /// [third-party identifier]: https://spec.matrix.org/v1.18/client-server-api/#adding-account-administrative-contact-information
859 ThreepidDenied,
860
861 /// `M_THREEPID_IN_USE`
862 ///
863 /// The [third-party identifier] is already in use by another user.
864 ///
865 /// [third-party identifier]: https://spec.matrix.org/v1.18/client-server-api/#adding-account-administrative-contact-information
866 ThreepidInUse,
867
868 /// `M_THREEPID_MEDIUM_NOT_SUPPORTED`
869 ///
870 /// The homeserver does not support adding a [third-party identifier] of the given medium.
871 ///
872 /// [third-party identifier]: https://spec.matrix.org/v1.18/client-server-api/#adding-account-administrative-contact-information
873 ThreepidMediumNotSupported,
874
875 /// `M_THREEPID_NOT_FOUND`
876 ///
877 /// No account matching the given [third-party identifier] could be found.
878 ///
879 /// [third-party identifier]: https://spec.matrix.org/v1.18/client-server-api/#adding-account-administrative-contact-information
880 ThreepidNotFound,
881
882 /// `M_TOKEN_INCORRECT`
883 ///
884 /// The token that the user entered to validate the session is incorrect.
885 TokenIncorrect,
886
887 /// `M_TOO_LARGE`
888 ///
889 /// The request or entity was too large.
890 TooLarge,
891
892 /// `M_UNABLE_TO_AUTHORISE_JOIN`
893 ///
894 /// The room is [restricted] and none of the conditions can be validated by the homeserver.
895 /// This can happen if the homeserver does not know about any of the rooms listed as
896 /// conditions, for example.
897 ///
898 /// [restricted]: https://spec.matrix.org/v1.18/client-server-api/#restricted-rooms
899 #[ruma_enum(rename = "M_UNABLE_TO_AUTHORISE_JOIN")]
900 UnableToAuthorizeJoin,
901
902 /// `M_UNABLE_TO_GRANT_JOIN`
903 ///
904 /// A different server should be attempted for the join. This is typically because the resident
905 /// server can see that the joining user satisfies one or more conditions, such as in the case
906 /// of [restricted rooms], but the resident server would be unable to meet the authorization
907 /// rules.
908 ///
909 /// [restricted rooms]: https://spec.matrix.org/v1.18/client-server-api/#restricted-rooms
910 UnableToGrantJoin,
911
912 /// `M_UNACTIONABLE`
913 ///
914 /// The server does not want to handle the [federated report].
915 ///
916 /// [federated report]: https://github.com/matrix-org/matrix-spec-proposals/pull/3843
917 #[cfg(feature = "unstable-msc3843")]
918 Unactionable,
919
920 /// `M_UNAUTHORIZED`
921 ///
922 /// The request was not correctly authorized. Usually due to login failures.
923 Unauthorized,
924
925 /// `M_UNKNOWN`
926 ///
927 /// An unknown error has occurred.
928 Unknown,
929
930 /// `M_UNKNOWN_POS`
931 ///
932 /// The sliding sync ([MSC4186]) connection was expired by the server.
933 ///
934 /// [MSC4186]: https://github.com/matrix-org/matrix-spec-proposals/pull/4186
935 #[cfg(feature = "unstable-msc4186")]
936 UnknownPos,
937
938 /// `M_UNKNOWN_TOKEN`
939 ///
940 /// The [access or refresh token] specified was not recognized.
941 ///
942 /// [access or refresh token]: https://spec.matrix.org/v1.18/client-server-api/#client-authentication
943 UnknownToken,
944
945 /// `M_UNRECOGNIZED`
946 ///
947 /// The server did not understand the request.
948 ///
949 /// This is expected to be returned with a 404 HTTP status code if the endpoint is not
950 /// implemented or a 405 HTTP status code if the endpoint is implemented, but the incorrect
951 /// HTTP method is used.
952 Unrecognized,
953
954 /// `M_UNSUPPORTED_ROOM_VERSION`
955 UnsupportedRoomVersion,
956
957 /// `M_URL_NOT_SET`
958 ///
959 /// The application service doesn't have a URL configured.
960 UrlNotSet,
961
962 /// `M_USER_DEACTIVATED`
963 ///
964 /// The user ID associated with the request has been deactivated.
965 UserDeactivated,
966
967 /// `M_USER_IN_USE`
968 ///
969 /// The desired user ID is already taken.
970 UserInUse,
971
972 /// `M_USER_LIMIT_EXCEEDED`
973 ///
974 /// The request cannot be completed because the user has exceeded (or the request would cause
975 /// them to exceed) a limit associated with their account. For example, a user may have reached
976 /// their allocated storage quota, reached a maximum number of allowed rooms, devices, or other
977 /// account-scoped resources, or exceeded usage limits for specific features.
978 UserLimitExceeded,
979
980 /// `M_USER_LOCKED`
981 ///
982 /// The account has been [locked] and cannot be used at this time.
983 ///
984 /// [locked]: https://spec.matrix.org/v1.18/client-server-api/#account-locking
985 UserLocked,
986
987 /// `M_USER_SUSPENDED`
988 ///
989 /// The account has been [suspended] and can only be used for limited actions at this time.
990 ///
991 /// [suspended]: https://spec.matrix.org/v1.18/client-server-api/#account-suspension
992 UserSuspended,
993
994 /// `M_WEAK_PASSWORD`
995 ///
996 /// The password was [rejected] by the server for being too weak.
997 ///
998 /// [rejected]: https://spec.matrix.org/v1.18/client-server-api/#password-management
999 WeakPassword,
1000
1001 /// `M_WRONG_ROOM_KEYS_VERSION`
1002 ///
1003 /// The version of the [room keys backup] provided in the request does not match the current
1004 /// backup version.
1005 ///
1006 /// [room keys backup]: https://spec.matrix.org/v1.18/client-server-api/#server-side-key-backups
1007 WrongRoomKeysVersion,
1008
1009 #[doc(hidden)]
1010 _Custom(PrivOwnedStr),
1011}