turbomcp_core/
error_utils.rs1use std::fmt;
7
8pub trait StandardErrorConversion<T> {
10 fn to_standard_error(self, context: &str) -> Result<T, String>;
12}
13
14impl<T, E: fmt::Display> StandardErrorConversion<T> for Result<T, E> {
15 fn to_standard_error(self, context: &str) -> Result<T, String> {
16 self.map_err(|e| format!("{context}: {e}"))
17 }
18}
19
20pub fn json_parse_error<T>(
22 result: Result<T, serde_json::Error>,
23 context: &str,
24) -> Result<T, String> {
25 result.map_err(|e| format!("{context}: {e}"))
26}
27
28pub fn io_error<T>(result: Result<T, std::io::Error>, context: &str) -> Result<T, String> {
30 result.map_err(|e| format!("{context}: {e}"))
31}
32
33pub fn network_error<T>(
35 result: Result<T, Box<dyn std::error::Error + Send + Sync>>,
36 context: &str,
37) -> Result<T, String> {
38 result.map_err(|e| format!("{context}: {e}"))
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44 use serde_json;
45
46 #[test]
47 fn test_standard_error_conversion() {
48 let result: Result<i32, &str> = Err("original error");
49 let converted = result.to_standard_error("Operation failed");
50 assert_eq!(converted.unwrap_err(), "Operation failed: original error");
51 }
52
53 #[test]
54 fn test_json_parse_error() {
55 let invalid_json = "{ invalid json";
56 let result: Result<serde_json::Value, _> = serde_json::from_str(invalid_json);
57 let converted = json_parse_error(result, "Failed to parse JSON");
58 assert!(converted.unwrap_err().starts_with("Failed to parse JSON:"));
59 }
60
61 #[test]
62 fn test_io_error() {
63 let result: Result<String, std::io::Error> = Err(std::io::Error::new(
64 std::io::ErrorKind::NotFound,
65 "file not found",
66 ));
67 let converted = io_error(result, "Failed to read file");
68 assert_eq!(
69 converted.unwrap_err(),
70 "Failed to read file: file not found"
71 );
72 }
73}