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