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 => StatusCode::GATEWAY_TIMEOUT,
60
61 | LimitExceeded { .. } => StatusCode::TOO_MANY_REQUESTS,
63
64 | TooLarge => StatusCode::PAYLOAD_TOO_LARGE,
66
67 | CannotOverwriteMedia => StatusCode::CONFLICT,
69
70 | NotFound | NotImplemented | FeatureDisabled | Unrecognized => StatusCode::NOT_FOUND,
72
73 | GuestAccessForbidden
75 | ThreepidAuthFailed
76 | UserDeactivated
77 | ThreepidDenied
78 | InviteBlocked
79 | WrongRoomKeysVersion { .. }
80 | Forbidden => StatusCode::FORBIDDEN,
81
82 | UnknownToken { .. } | MissingToken | Unauthorized => StatusCode::UNAUTHORIZED,
84
85 | _ => StatusCode::BAD_REQUEST,
87 }
88}
89
90pub(super) fn ruma_error_message(error: &ruma::api::error::Error) -> String {
91 if let ErrorBody::Standard(ruma::api::error::StandardErrorBody { message, .. }) = &error.body
92 {
93 return message.clone();
94 }
95
96 format!("{error}")
97}
98
99pub(super) fn ruma_error_kind(e: &ruma::api::error::Error) -> &ErrorKind {
100 e.error_kind().unwrap_or(&ErrorKind::Unknown)
101}
102
103pub(super) fn io_error_code(kind: std::io::ErrorKind) -> StatusCode {
104 use std::io::ErrorKind;
105
106 match kind {
107 | ErrorKind::InvalidInput => StatusCode::BAD_REQUEST,
108 | ErrorKind::PermissionDenied => StatusCode::FORBIDDEN,
109 | ErrorKind::NotFound => StatusCode::NOT_FOUND,
110 | ErrorKind::TimedOut => StatusCode::GATEWAY_TIMEOUT,
111 | ErrorKind::FileTooLarge => StatusCode::PAYLOAD_TOO_LARGE,
112 | ErrorKind::StorageFull => StatusCode::INSUFFICIENT_STORAGE,
113 | ErrorKind::Interrupted => StatusCode::SERVICE_UNAVAILABLE,
114 | _ => StatusCode::INTERNAL_SERVER_ERROR,
115 }
116}