Skip to main content

reinhardt_admin/server/
error.rs

1//! Error conversion for Server Functions
2//!
3//! This module provides error conversion from AdminError to ServerFnError.
4
5use crate::types::AdminError;
6use reinhardt_pages::server_fn::ServerFnError;
7
8/// Extension trait for converting AdminError to ServerFnError
9pub trait IntoServerFnError {
10	/// Convert AdminError to ServerFnError
11	fn into_server_fn_error(self) -> ServerFnError;
12}
13
14impl IntoServerFnError for AdminError {
15	fn into_server_fn_error(self) -> ServerFnError {
16		match self {
17			AdminError::ModelNotRegistered(msg) => ServerFnError::server(404, msg),
18			AdminError::PermissionDenied(msg) => ServerFnError::server(403, msg),
19			AdminError::InvalidAction(msg) | AdminError::ValidationError(msg) => {
20				ServerFnError::application(msg)
21			}
22			AdminError::DatabaseError(_) => {
23				// Hide internal database error details from clients
24				ServerFnError::server(500, "Database operation failed")
25			}
26			AdminError::TemplateError(_) => {
27				// Hide internal template error details from clients
28				ServerFnError::server(500, "Template rendering failed")
29			}
30		}
31	}
32}
33
34/// Convert `Result<T, AdminError>` to `Result<T, ServerFnError>`
35pub trait MapServerFnError<T> {
36	/// Map AdminError to ServerFnError
37	fn map_server_fn_error(self) -> Result<T, ServerFnError>;
38}
39
40impl<T> MapServerFnError<T> for Result<T, AdminError> {
41	fn map_server_fn_error(self) -> Result<T, ServerFnError> {
42		self.map_err(|e| e.into_server_fn_error())
43	}
44}
45
46#[cfg(test)]
47mod tests {
48	use super::*;
49
50	#[test]
51	fn test_model_not_registered_converts_to_404() {
52		let admin_err = AdminError::ModelNotRegistered("User".into());
53		let server_err = admin_err.into_server_fn_error();
54
55		match server_err {
56			ServerFnError::Server { status, message } => {
57				assert_eq!(status, 404);
58				assert_eq!(message, "User");
59			}
60			_ => panic!("Expected Server error"),
61		}
62	}
63
64	#[test]
65	fn test_permission_denied_converts_to_403() {
66		let admin_err = AdminError::PermissionDenied("Access denied".into());
67		let server_err = admin_err.into_server_fn_error();
68
69		match server_err {
70			ServerFnError::Server { status, message } => {
71				assert_eq!(status, 403);
72				assert_eq!(message, "Access denied");
73			}
74			_ => panic!("Expected Server error"),
75		}
76	}
77
78	#[test]
79	fn test_validation_error_converts_to_application() {
80		let admin_err = AdminError::ValidationError("Invalid input".into());
81		let server_err = admin_err.into_server_fn_error();
82
83		match server_err {
84			ServerFnError::Application(msg) => {
85				assert_eq!(msg, "Invalid input");
86			}
87			_ => panic!("Expected Application error"),
88		}
89	}
90
91	#[test]
92	fn test_database_error_hides_details() {
93		let admin_err = AdminError::DatabaseError("SQL syntax error at line 42".into());
94		let server_err = admin_err.into_server_fn_error();
95
96		match server_err {
97			ServerFnError::Server { status, message } => {
98				assert_eq!(status, 500);
99				assert_eq!(message, "Database operation failed");
100				// Verify that the original error details are hidden
101				assert!(!message.contains("SQL"));
102				assert!(!message.contains("42"));
103			}
104			_ => panic!("Expected Server error"),
105		}
106	}
107
108	#[test]
109	fn test_result_conversion() {
110		let result: Result<String, AdminError> = Err(AdminError::ModelNotRegistered("Post".into()));
111		let server_result = result.map_server_fn_error();
112
113		assert!(server_result.is_err());
114		match server_result.unwrap_err() {
115			ServerFnError::Server { status, .. } => assert_eq!(status, 404),
116			_ => panic!("Expected Server error"),
117		}
118	}
119}