soaprs_http/
error_mapping.rs1use http::StatusCode;
4use soaprs_core::{SoapError, SoapErrorKind};
5
6pub const fn default_error_status(error: &SoapError) -> StatusCode {
10 match error.kind() {
11 SoapErrorKind::NotFound => StatusCode::NOT_FOUND,
12 SoapErrorKind::Validation | SoapErrorKind::Domain => StatusCode::UNPROCESSABLE_ENTITY,
13 SoapErrorKind::Conflict => StatusCode::CONFLICT,
14 SoapErrorKind::Unauthorized => StatusCode::UNAUTHORIZED,
15 SoapErrorKind::Forbidden => StatusCode::FORBIDDEN,
16 SoapErrorKind::Unsupported => StatusCode::NOT_IMPLEMENTED,
17 SoapErrorKind::Timeout => StatusCode::GATEWAY_TIMEOUT,
18 SoapErrorKind::Unavailable => StatusCode::SERVICE_UNAVAILABLE,
19 SoapErrorKind::Infrastructure => StatusCode::INTERNAL_SERVER_ERROR,
20 }
21}
22
23#[cfg(test)]
24mod tests {
25 use http::StatusCode;
26 use soaprs_core::SoapError;
27
28 use super::default_error_status;
29
30 #[test]
31 fn distinguishes_authentication_and_authorization() {
32 assert_eq!(
33 default_error_status(&SoapError::unauthorized()),
34 StatusCode::UNAUTHORIZED
35 );
36 assert_eq!(
37 default_error_status(&SoapError::forbidden()),
38 StatusCode::FORBIDDEN
39 );
40 }
41
42 #[test]
43 fn maps_stable_error_categories_to_default_statuses() {
44 let cases = [
45 (SoapError::not_found("user"), StatusCode::NOT_FOUND),
46 (
47 SoapError::validation("invalid email"),
48 StatusCode::UNPROCESSABLE_ENTITY,
49 ),
50 (
51 SoapError::domain("account is closed"),
52 StatusCode::UNPROCESSABLE_ENTITY,
53 ),
54 (SoapError::conflict("email exists"), StatusCode::CONFLICT),
55 (
56 SoapError::unsupported("full-text search"),
57 StatusCode::NOT_IMPLEMENTED,
58 ),
59 (
60 SoapError::timeout("database query"),
61 StatusCode::GATEWAY_TIMEOUT,
62 ),
63 (
64 SoapError::unavailable("database"),
65 StatusCode::SERVICE_UNAVAILABLE,
66 ),
67 (
68 SoapError::infrastructure("database operation"),
69 StatusCode::INTERNAL_SERVER_ERROR,
70 ),
71 ];
72
73 for (error, expected) in cases {
74 assert_eq!(default_error_status(&error), expected);
75 }
76 }
77}