Fix error swallowing by propagating JSON serialization errors to LLM

This commit is contained in:
Riz Ashraf committed 2026-09-27 09:44:04 +01:00
1 parent 48a1973ea6
commit 01d3c22c57
6 files changed
+59 -59

No files matched your search

+4 -4
View File
@@ -62,7 +62,7 @@ impl McpTool for ReadEnvFingerprintHandler {
.read_with(|fps| fps.get(&req.namespace).cloned()); .read_with(|fps| fps.get(&req.namespace).cloned());
if let Some(fp) = data { if let Some(fp) = data {
let data = serde_json::to_string(&fp).unwrap_or_default(); let data = serde_json::to_string(&fp).unwrap_or_default();
Ok(data.to_string()) Ok(data)
} else { } else {
Ok("{}".to_string()) Ok("{}".to_string())
} }
@@ -155,9 +155,9 @@ impl McpTool for GetEnvironmentDetailsHandler {
.iter() .iter()
.filter(|e| e.namespace == req.namespace) .filter(|e| e.namespace == req.namespace)
.collect(); .collect();
serde_json::to_string(&filtered).unwrap_or_default() serde_json::to_string(&filtered).map_err(|e| e.to_string())
}); })?;
Ok(data.to_string()) Ok(data)
} }
} }
+5 -5
View File
@@ -380,8 +380,8 @@ impl McpTool for SearchNodesHandler {
result.entities.insert(id, e); result.entities.insert(id, e);
} }
} }
serde_json::to_string(&result).unwrap_or_default() serde_json::to_string(&result).map_err(|e| e.to_string())
}); })?;
Ok(data) Ok(data)
} }
} }
@@ -418,8 +418,8 @@ impl McpTool for OpenNodesHandler {
result.entities.insert(name, e); result.entities.insert(name, e);
} }
} }
serde_json::to_string(&result).unwrap_or_default() serde_json::to_string(&result).map_err(|e| e.to_string())
}); })?;
Ok(data) Ok(data)
} }
} }
@@ -620,7 +620,7 @@ impl McpTool for FindOrphansHandler {
.collect::<Vec<String>>() .collect::<Vec<String>>()
}); });
let data = serde_json::to_string(&orphans).unwrap_or_default(); let data = serde_json::to_string(&orphans).unwrap_or_default();
Ok(data.to_string()) Ok(data)
} }
} }
+26 -26
View File
@@ -70,9 +70,9 @@ impl McpTool for QueryDecisionsHandler {
} }
}) })
.collect(); .collect();
serde_json::to_string(&filtered).unwrap_or_default() serde_json::to_string(&filtered).map_err(|e| e.to_string())
}); })?;
Ok(data.to_string()) Ok(data)
} }
} }
@@ -129,9 +129,9 @@ impl McpTool for SearchErrorFixesHandler {
|| contains_ignore_ascii_case(&f.solution, &q) || contains_ignore_ascii_case(&f.solution, &q)
}) })
.collect(); .collect();
serde_json::to_string(&filtered).unwrap_or_default() serde_json::to_string(&filtered).map_err(|e| e.to_string())
}); })?;
Ok(data.to_string()) Ok(data)
} }
} }
@@ -180,8 +180,8 @@ impl McpTool for QueryRecentChangesHandler {
async fn execute(&self, _args: Value, state: Arc<MemoryState>) -> Result<String, String> { async fn execute(&self, _args: Value, state: Arc<MemoryState>) -> Result<String, String> {
let data = state let data = state
.ledger .ledger
.read_with(|l| serde_json::to_string(l).unwrap_or_else(|_| "[]".to_string())); .read_with(|l| serde_json::to_string(l).map_err(|e| e.to_string()))?;
Ok(data.to_string()) Ok(data)
} }
} }
@@ -229,7 +229,7 @@ impl McpTool for ReadPreferencesHandler {
let data = state let data = state
.prefs .prefs
.read_with(|prefs| serde_json::to_string(prefs).unwrap_or_default()); .read_with(|prefs| serde_json::to_string(prefs).unwrap_or_default());
Ok(data.to_string()) Ok(data)
} }
} }
@@ -319,9 +319,9 @@ impl McpTool for ListTechDebtHandler {
d.namespace == req.namespace && (req.include_resolved || !d.is_resolved) d.namespace == req.namespace && (req.include_resolved || !d.is_resolved)
}) })
.collect(); .collect();
serde_json::to_string(&filtered).unwrap_or_default() serde_json::to_string(&filtered).map_err(|e| e.to_string())
}); })?;
Ok(data.to_string()) Ok(data)
} }
} }
@@ -370,8 +370,8 @@ impl McpTool for OmniSearchHandler {
} }
} }
} }
serde_json::to_value(&kg_entities).unwrap_or_default() serde_json::to_value(&kg_entities).map_err(|e| e.to_string())
}); })?;
let mut matched_tasks = std::collections::HashSet::new(); let mut matched_tasks = std::collections::HashSet::new();
let mut matched_snippets = std::collections::HashSet::new(); let mut matched_snippets = std::collections::HashSet::new();
@@ -407,8 +407,8 @@ impl McpTool for OmniSearchHandler {
} }
}) })
.collect(); .collect();
serde_json::to_value(&filtered).unwrap_or_default() serde_json::to_value(&filtered).map_err(|e| e.to_string())
}); })?;
let snippets_json = state.snippets.read_with(|all_snippets| { let snippets_json = state.snippets.read_with(|all_snippets| {
let filtered: Vec<_> = all_snippets let filtered: Vec<_> = all_snippets
@@ -425,8 +425,8 @@ impl McpTool for OmniSearchHandler {
} }
}) })
.collect(); .collect();
serde_json::to_value(&filtered).unwrap_or_default() serde_json::to_value(&filtered).map_err(|e| e.to_string())
}); })?;
let adrs_json = state.adrs.read_with(|all_adrs| { let adrs_json = state.adrs.read_with(|all_adrs| {
let filtered: Vec<_> = all_adrs let filtered: Vec<_> = all_adrs
@@ -445,8 +445,8 @@ impl McpTool for OmniSearchHandler {
} }
}) })
.collect(); .collect();
serde_json::to_value(&filtered).unwrap_or_default() serde_json::to_value(&filtered).map_err(|e| e.to_string())
}); })?;
let q = req.query; let q = req.query;
let tech_debts_json = state.tech_debts.read_with(|debts| { let tech_debts_json = state.tech_debts.read_with(|debts| {
@@ -469,8 +469,8 @@ impl McpTool for OmniSearchHandler {
} }
}) })
.collect(); .collect();
serde_json::to_value(&filtered).unwrap_or_default() serde_json::to_value(&filtered).map_err(|e| e.to_string())
}); })?;
let memos_json = state.handoff_memos.read_with(|memos| { let memos_json = state.handoff_memos.read_with(|memos| {
let filtered: Vec<_> = memos let filtered: Vec<_> = memos
@@ -490,8 +490,8 @@ impl McpTool for OmniSearchHandler {
} }
}) })
.collect(); .collect();
serde_json::to_value(&filtered).unwrap_or_default() serde_json::to_value(&filtered).map_err(|e| e.to_string())
}); })?;
let error_fixes_json = state.error_fixes.read_with(|fixes| { let error_fixes_json = state.error_fixes.read_with(|fixes| {
let filtered: Vec<_> = fixes let filtered: Vec<_> = fixes
@@ -501,8 +501,8 @@ impl McpTool for OmniSearchHandler {
|| contains_ignore_ascii_case(&f.solution, &q) || contains_ignore_ascii_case(&f.solution, &q)
}) })
.collect(); .collect();
serde_json::to_value(&filtered).unwrap_or_default() serde_json::to_value(&filtered).map_err(|e| e.to_string())
}); })?;
let report = serde_json::json!({ let report = serde_json::json!({
"knowledge_graph": kg_json, "knowledge_graph": kg_json,
+5 -5
View File
@@ -49,8 +49,8 @@ impl McpTool for ReadStickyNotesHandler {
async fn execute(&self, _args: Value, state: Arc<MemoryState>) -> Result<String, String> { async fn execute(&self, _args: Value, state: Arc<MemoryState>) -> Result<String, String> {
let data = state let data = state
.sticky .sticky
.read_with(|s| serde_json::to_string(s).unwrap_or_else(|_| "[]".to_string())); .read_with(|s| serde_json::to_string(s).map_err(|e| e.to_string()))?;
Ok(data.to_string()) Ok(data)
} }
} }
@@ -167,9 +167,9 @@ impl McpTool for ReadHandoffMemosHandler {
} }
}) })
.collect(); .collect();
serde_json::to_string(&filtered).unwrap_or_default() serde_json::to_string(&filtered).map_err(|e| e.to_string())
}); })?;
Ok(data.to_string()) Ok(data)
} }
} }
+4 -4
View File
@@ -293,8 +293,8 @@ impl McpTool for ListActiveTasksHandler {
status_match && branch_match status_match && branch_match
}) })
.collect(); .collect();
serde_json::to_string(&filtered).unwrap_or_default() serde_json::to_string(&filtered).map_err(|e| e.to_string())
}); })?;
Ok(data) Ok(data)
} }
} }
@@ -474,8 +474,8 @@ impl McpTool for ListMilestonesHandler {
} }
}) })
.collect(); .collect();
serde_json::to_string(&filtered).unwrap_or_default() serde_json::to_string(&filtered).map_err(|e| e.to_string())
}); })?;
Ok(data) Ok(data)
} }
} }
+15 -15
View File
@@ -89,9 +89,9 @@ impl McpTool for ListPinnedFilesHandler {
ns_match && branch_match ns_match && branch_match
}) })
.collect(); .collect();
serde_json::to_string(&filtered).unwrap_or_default() serde_json::to_string(&filtered).map_err(|e| e.to_string())
}); })?;
Ok(data.to_string()) Ok(data)
} }
} }
@@ -154,9 +154,9 @@ impl McpTool for SearchSnippetsHandler {
|| contains_ignore_ascii_case(&s.language, &query) || contains_ignore_ascii_case(&s.language, &query)
}) })
.collect(); .collect();
serde_json::to_string(&results).unwrap_or_default() serde_json::to_string(&results).map_err(|e| e.to_string())
}); })?;
Ok(data.to_string()) Ok(data)
} }
} }
@@ -245,9 +245,9 @@ impl McpTool for LoadContextWorkspaceHandler {
.iter() .iter()
.filter(|w| w.namespace == req.namespace && w.name == req.name) .filter(|w| w.namespace == req.namespace && w.name == req.name)
.collect(); .collect();
serde_json::to_string(&filtered.first()).unwrap_or_default() serde_json::to_string(&filtered.first()).map_err(|e| e.to_string())
}); })?;
Ok(data.to_string()) Ok(data)
} }
} }
@@ -271,9 +271,9 @@ impl McpTool for ListContextWorkspacesHandler {
serde_json::from_value(args).map_err(|e| e.to_string())?; serde_json::from_value(args).map_err(|e| e.to_string())?;
let data = state.context_workspaces.read_with(|ws| { let data = state.context_workspaces.read_with(|ws| {
let filtered: Vec<_> = ws.iter().filter(|w| req.namespace.as_ref().map_or(true, |ns| &w.namespace == ns)).collect(); let filtered: Vec<_> = ws.iter().filter(|w| req.namespace.as_ref().map_or(true, |ns| &w.namespace == ns)).collect();
serde_json::to_string(&filtered).unwrap_or_default() serde_json::to_string(&filtered).map_err(|e| e.to_string())
}); })?;
Ok(data.to_string()) Ok(data)
} }
} }
@@ -325,9 +325,9 @@ impl McpTool for GetPrChecklistHandler {
.iter() .iter()
.filter(|i| i.namespace == req.namespace) .filter(|i| i.namespace == req.namespace)
.collect(); .collect();
serde_json::to_string(&filtered).unwrap_or_default() serde_json::to_string(&filtered).map_err(|e| e.to_string())
}); })?;
Ok(data.to_string()) Ok(data)
} }
} }