tuwunel_core/error/
response.rs1use bytes::BytesMut;
2use http::StatusCode;
3use http_body_util::Full;
4use ruma::api::{
5 OutgoingResponse,
6 client::uiaa::UiaaResponse,
7 error::{ErrorBody, ErrorKind},
8};
9
10use super::Error;
11use crate::error;
12
13impl axum::response::IntoResponse for Error {
14 fn into_response(self) -> axum::response::Response {
15 let response: UiaaResponse = self.into();
16 response
17 .try_into_http_response::<BytesMut>()
18 .inspect_err(|e| error!("error response error: {e}"))
19 .map_or_else(
20 |_| StatusCode::INTERNAL_SERVER_ERROR.into_response(),
21 |r| {
22 r.map(BytesMut::freeze)
23 .map(Full::new)
24 .into_response()
25 },
26 )
27 }
28}
29
30impl From<Error> for UiaaResponse {
31 #[inline]
32 fn from(error: Error) -> Self {
33 if let Error::Uiaa(uiaainfo) = error {
34 return Self::AuthResponse(uiaainfo);
35 }
36
37 let body = ErrorBody::Standard(ruma::api::error::StandardErrorBody {
38 kind: error.kind(),
39 message: error.message(),
40 });
41
42 Self::MatrixError(ruma::api::error::Error::new(error.status_code(), body))
43 }
44}
45
46pub(super) fn status_code(kind: &ErrorKind, hint: StatusCode) -> StatusCode {
47 if hint == StatusCode::BAD_REQUEST {
48 bad_request_code(kind)
49 } else {
50 hint
51 }
52}
53
54pub(super) fn bad_request_code(kind: &ErrorKind) -> StatusCode {
55 use ErrorKind::*;
56
57 match kind {
58 | NotYetUploaded | ConnectionTimeout => StatusCode::GATEWAY_TIMEOUT,
60
61 | BadStatus(..) | ConnectionFailed => StatusCode::BAD_GATEWAY,
63
64 | LimitExceeded { .. } => StatusCode::TOO_MANY_REQUESTS,
66
67 | TooLarge => StatusCode::PAYLOAD_TOO_LARGE,
69
70 | CannotOverwriteMedia => StatusCode::CONFLICT,
72
73 | NotFound | NotImplemented | FeatureDisabled | Unrecognized => StatusCode::NOT_FOUND,
75
76 | GuestAccessForbidden
78 | ThreepidAuthFailed
79 | UserDeactivated
80 | ThreepidDenied
81 | InviteBlocked
82 | WrongRoomKeysVersion { .. }
83 | Forbidden => StatusCode::FORBIDDEN,
84
85 | UnknownToken { .. } | MissingToken | Unauthorized => StatusCode::UNAUTHORIZED,
87
88 | _ => StatusCode::BAD_REQUEST,
90 }
91}
92
93pub(super) fn ruma_error_message(error: &ruma::api::error::Error) -> String {
94 if let ErrorBody::Standard(ruma::api::error::StandardErrorBody { message, .. }) = &error.body
95 {
96 return message.clone();
97 }
98
99 format!("{error}")
100}
101
102pub(super) fn ruma_error_kind(e: &ruma::api::error::Error) -> &ErrorKind {
103 e.error_kind().unwrap_or(&ErrorKind::Unknown)
104}
105
106pub(super) fn io_error_code(kind: std::io::ErrorKind) -> StatusCode {
107 use std::io::ErrorKind;
108
109 match kind {
110 | ErrorKind::InvalidInput => StatusCode::BAD_REQUEST,
111 | ErrorKind::PermissionDenied => StatusCode::FORBIDDEN,
112 | ErrorKind::NotFound => StatusCode::NOT_FOUND,
113 | ErrorKind::TimedOut => StatusCode::GATEWAY_TIMEOUT,
114 | ErrorKind::FileTooLarge => StatusCode::PAYLOAD_TOO_LARGE,
115 | ErrorKind::StorageFull => StatusCode::INSUFFICIENT_STORAGE,
116 | ErrorKind::Interrupted => StatusCode::SERVICE_UNAVAILABLE,
117 | _ => StatusCode::INTERNAL_SERVER_ERROR,
118 }
119}