fix(mcp): propagate internal serialization errors instead of silently swallowing them to prevent LLM hallucination
This commit is contained in:
1 parent
f8925050db
commit
8f32a09399
13 files changed
+235
-63
No files matched your search
+27
-12
@@ -98,11 +98,15 @@ impl McpTool for DeleteDecisionHandler {
|
||||
}
|
||||
|
||||
fn schema(&self) -> Value {
|
||||
crate::mcp::tool_def::<crate::tools::DeleteDecisionTool>("delete_decision", "Delete an architectural decision record")
|
||||
crate::mcp::tool_def::<crate::tools::DeleteDecisionTool>(
|
||||
"delete_decision",
|
||||
"Delete an architectural decision record",
|
||||
)
|
||||
}
|
||||
|
||||
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
|
||||
let req: crate::tools::DeleteDecisionTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||
let req: crate::tools::DeleteDecisionTool =
|
||||
serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||
let mut found = false;
|
||||
state.adrs.modify(|adrs| {
|
||||
if let Some(pos) = adrs.iter().position(|a| a.id == req.id) {
|
||||
@@ -110,7 +114,7 @@ impl McpTool for DeleteDecisionHandler {
|
||||
found = true;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if found {
|
||||
state.rebuild_index().await;
|
||||
Ok("Decision deleted successfully".to_string())
|
||||
@@ -337,7 +341,10 @@ impl McpTool for ResolveTechDebtHandler {
|
||||
if found {
|
||||
Ok("Tech debt resolved".to_string())
|
||||
} else {
|
||||
Err("Tech debt not found. Please verify the tech debt ID using list_tech_debt.".to_string())
|
||||
Err(
|
||||
"Tech debt not found. Please verify the tech debt ID using list_tech_debt."
|
||||
.to_string(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -385,7 +392,10 @@ impl McpTool for OmniSearchHandler {
|
||||
let req: OmniSearchTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||
let limit = req.limit.unwrap_or(5);
|
||||
let include_body = req.include_body.unwrap_or(false);
|
||||
let matches = match state.get_search_index().search(&req.query, req.namespace.as_deref()) {
|
||||
let matches = match state
|
||||
.get_search_index()
|
||||
.search(&req.query, req.namespace.as_deref())
|
||||
{
|
||||
Ok(m) => m,
|
||||
Err(e) => {
|
||||
return Err(format!(
|
||||
@@ -403,7 +413,9 @@ impl McpTool for OmniSearchHandler {
|
||||
if doc_type == "entity"
|
||||
&& let Some(e) = full.entities.get(id)
|
||||
{
|
||||
if count >= limit { continue; }
|
||||
if count >= limit {
|
||||
continue;
|
||||
}
|
||||
count += 1;
|
||||
if !include_body {
|
||||
let mut summary = e.clone();
|
||||
@@ -792,13 +804,13 @@ mod tests {
|
||||
dependencies: vec![],
|
||||
acceptance_criteria: vec![],
|
||||
};
|
||||
|
||||
|
||||
{
|
||||
state.tasks.modify(|t| {
|
||||
t.push(task.clone());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
state.rebuild_index().await;
|
||||
state.get_search_index().reader.reload().unwrap();
|
||||
|
||||
@@ -808,21 +820,24 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
println!("OMNI RES: {}", omni_res);
|
||||
assert!(omni_res.contains("omni-1"), "omni search should return results containing the task id");
|
||||
assert!(
|
||||
omni_res.contains("omni-1"),
|
||||
"omni search should return results containing the task id"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_omni_search_malformed_query() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let state = Arc::new(MemoryState::new(dir.path().to_str().unwrap()));
|
||||
|
||||
|
||||
let omni = OmniSearchHandler;
|
||||
|
||||
|
||||
// Pass a malformed Lucene query (unclosed parenthesis)
|
||||
let omni_res = omni
|
||||
.execute(json!({"query": "title: (unclosed"}), state.clone())
|
||||
.await;
|
||||
|
||||
|
||||
assert!(omni_res.is_err());
|
||||
let err_msg = omni_res.unwrap_err();
|
||||
assert!(err_msg.contains("malformed Lucene syntax"));
|
||||
|
||||
Reference in new issue
Block a user