http_tunnel_handler/
error_handling.rs1use tracing::error;
7
8pub fn sanitize_error(e: &anyhow::Error) -> String {
13 error!("Internal error: {:#}", e);
15
16 "Internal server error".to_string()
18}
19
20pub fn sanitize_error_with_message(e: &anyhow::Error, client_message: &str) -> String {
24 error!("Error ({}): {:#}", client_message, e);
26
27 client_message.to_string()
29}
30
31pub fn is_safe_error(e: &anyhow::Error) -> bool {
36 let error_str = format!("{}", e);
37 let error_debug = format!("{:?}", e);
38
39 error_str.contains("Invalid tunnel ID")
41 || error_str.contains("Invalid request ID")
42 || error_str.contains("Invalid connection ID")
43 || error_str.contains("Path too long")
44 || error_str.contains("Header value too long")
45 || error_str.contains("Request timeout")
46 || error_str.contains("Missing tunnel ID")
47 || error_str.contains("Request entity too large")
48 || error_debug.contains("ValidationError")
49}
50
51pub fn get_client_error_message(e: &anyhow::Error) -> String {
55 if is_safe_error(e) {
56 error!("Client error: {}", e);
58 format!("{}", e)
59 } else {
60 sanitize_error(e)
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use anyhow::anyhow;
69
70 #[test]
71 fn test_sanitize_error_hides_details() {
72 let err = anyhow!("Failed to connect to DynamoDB at 10.0.1.5:8000");
73 let sanitized = sanitize_error(&err);
74
75 assert_eq!(sanitized, "Internal server error");
76 assert!(!sanitized.contains("DynamoDB"));
77 assert!(!sanitized.contains("10.0.1.5"));
78 }
79
80 #[test]
81 fn test_sanitize_error_with_custom_message() {
82 let err = anyhow!("AWS IAM credentials not found");
83 let sanitized = sanitize_error_with_message(&err, "Service temporarily unavailable");
84
85 assert_eq!(sanitized, "Service temporarily unavailable");
86 assert!(!sanitized.contains("IAM"));
87 assert!(!sanitized.contains("credentials"));
88 }
89
90 #[test]
91 fn test_safe_errors_are_identified() {
92 let validation_err = anyhow!("Invalid tunnel ID format: ABC");
93 assert!(is_safe_error(&validation_err));
94
95 let timeout_err = anyhow!("Request timeout waiting for response");
96 assert!(is_safe_error(&timeout_err));
97
98 let db_err = anyhow!("DynamoDB throttling error");
99 assert!(!is_safe_error(&db_err));
100 }
101
102 #[test]
103 fn test_client_error_message() {
104 let safe_err = anyhow!("Invalid tunnel ID format: test");
106 let msg = get_client_error_message(&safe_err);
107 assert!(msg.contains("Invalid tunnel ID"));
108
109 let unsafe_err = anyhow!("AWS SDK error: InvalidParameterException");
111 let msg = get_client_error_message(&unsafe_err);
112 assert_eq!(msg, "Internal server error");
113 assert!(!msg.contains("AWS"));
114 }
115}