use tracing::error;
pub fn sanitize_error(e: &anyhow::Error) -> String {
error!("Internal error: {:#}", e);
"Internal server error".to_string()
}
pub fn sanitize_error_with_message(e: &anyhow::Error, client_message: &str) -> String {
error!("Error ({}): {:#}", client_message, e);
client_message.to_string()
}
pub fn is_safe_error(e: &anyhow::Error) -> bool {
let error_str = format!("{}", e);
let error_debug = format!("{:?}", e);
error_str.contains("Invalid tunnel ID")
|| error_str.contains("Invalid request ID")
|| error_str.contains("Invalid connection ID")
|| error_str.contains("Path too long")
|| error_str.contains("Header value too long")
|| error_str.contains("Request timeout")
|| error_str.contains("Missing tunnel ID")
|| error_str.contains("Request entity too large")
|| error_debug.contains("ValidationError")
}
pub fn get_client_error_message(e: &anyhow::Error) -> String {
if is_safe_error(e) {
error!("Client error: {}", e);
format!("{}", e)
} else {
sanitize_error(e)
}
}
#[cfg(test)]
mod tests {
use super::*;
use anyhow::anyhow;
#[test]
fn test_sanitize_error_hides_details() {
let err = anyhow!("Failed to connect to DynamoDB at 10.0.1.5:8000");
let sanitized = sanitize_error(&err);
assert_eq!(sanitized, "Internal server error");
assert!(!sanitized.contains("DynamoDB"));
assert!(!sanitized.contains("10.0.1.5"));
}
#[test]
fn test_sanitize_error_with_custom_message() {
let err = anyhow!("AWS IAM credentials not found");
let sanitized = sanitize_error_with_message(&err, "Service temporarily unavailable");
assert_eq!(sanitized, "Service temporarily unavailable");
assert!(!sanitized.contains("IAM"));
assert!(!sanitized.contains("credentials"));
}
#[test]
fn test_safe_errors_are_identified() {
let validation_err = anyhow!("Invalid tunnel ID format: ABC");
assert!(is_safe_error(&validation_err));
let timeout_err = anyhow!("Request timeout waiting for response");
assert!(is_safe_error(&timeout_err));
let db_err = anyhow!("DynamoDB throttling error");
assert!(!is_safe_error(&db_err));
}
#[test]
fn test_client_error_message() {
let safe_err = anyhow!("Invalid tunnel ID format: test");
let msg = get_client_error_message(&safe_err);
assert!(msg.contains("Invalid tunnel ID"));
let unsafe_err = anyhow!("AWS SDK error: InvalidParameterException");
let msg = get_client_error_message(&unsafe_err);
assert_eq!(msg, "Internal server error");
assert!(!msg.contains("AWS"));
}
}