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
@@ -151,8 +151,14 @@ impl McpTool for CreateRelationsHandler {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
let err_msg = e.to_string();
|
||||
if err_msg.contains("missing field `from`") || err_msg.contains("missing field `to`") || err_msg.contains("missing field `relation_type`") {
|
||||
return Err(format!("Schema error: {}. Note that the relation schema strictly uses 'from', 'to', and 'relation_type' (not 'source', 'target', or 'relationType'). Please correct your tool call arguments.", err_msg));
|
||||
if err_msg.contains("missing field `from`")
|
||||
|| err_msg.contains("missing field `to`")
|
||||
|| err_msg.contains("missing field `relation_type`")
|
||||
{
|
||||
return Err(format!(
|
||||
"Schema error: {}. Note that the relation schema strictly uses 'from', 'to', and 'relation_type' (not 'source', 'target', or 'relationType'). Please correct your tool call arguments.",
|
||||
err_msg
|
||||
));
|
||||
}
|
||||
return Err(err_msg);
|
||||
}
|
||||
@@ -166,15 +172,22 @@ impl McpTool for CreateRelationsHandler {
|
||||
if from_exists && to_exists {
|
||||
g.relations.push(relation);
|
||||
} else {
|
||||
if !from_exists { missing_nodes.insert(relation.from); }
|
||||
if !to_exists { missing_nodes.insert(relation.to); }
|
||||
if !from_exists {
|
||||
missing_nodes.insert(relation.from);
|
||||
}
|
||||
if !to_exists {
|
||||
missing_nodes.insert(relation.to);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if !missing_nodes.is_empty() {
|
||||
let missing: Vec<_> = missing_nodes.into_iter().collect();
|
||||
return Err(format!("Error: Relations dropped due to missing entities: {}", missing.join(", ")));
|
||||
return Err(format!(
|
||||
"Error: Relations dropped due to missing entities: {}",
|
||||
missing.join(", ")
|
||||
));
|
||||
}
|
||||
Ok("Relations created".to_string())
|
||||
}
|
||||
@@ -205,7 +218,10 @@ impl McpTool for AddObservationsHandler {
|
||||
}
|
||||
});
|
||||
if !missing_entities.is_empty() {
|
||||
return Err(format!("Error: Observations dropped for missing entities: {}", missing_entities.join(", ")));
|
||||
return Err(format!(
|
||||
"Error: Observations dropped for missing entities: {}",
|
||||
missing_entities.join(", ")
|
||||
));
|
||||
}
|
||||
Ok("Observations added".to_string())
|
||||
}
|
||||
@@ -239,7 +255,10 @@ impl McpTool for DeleteEntitiesHandler {
|
||||
});
|
||||
|
||||
if !missing.is_empty() {
|
||||
return Err(format!("Error: Entities not found: {}. Please use the search_nodes or read_graph tools to verify the exact entity names.", missing.join(", ")));
|
||||
return Err(format!(
|
||||
"Error: Entities not found: {}. Please use the search_nodes or read_graph tools to verify the exact entity names.",
|
||||
missing.join(", ")
|
||||
));
|
||||
}
|
||||
|
||||
let idx = state.get_search_index();
|
||||
@@ -280,7 +299,10 @@ impl McpTool for DeleteObservationsHandler {
|
||||
}
|
||||
});
|
||||
if !missing.is_empty() {
|
||||
return Err(format!("Error: Entities not found: {}. Please use the search_nodes or read_graph tools to verify the exact entity names.", missing.join(", ")));
|
||||
return Err(format!(
|
||||
"Error: Entities not found: {}. Please use the search_nodes or read_graph tools to verify the exact entity names.",
|
||||
missing.join(", ")
|
||||
));
|
||||
}
|
||||
Ok("Observations deleted".to_string())
|
||||
}
|
||||
@@ -308,7 +330,10 @@ impl McpTool for DeleteRelationsHandler {
|
||||
missing_count = to_rem.len() - (initial_len - master.relations.len());
|
||||
});
|
||||
if missing_count > 0 {
|
||||
return Err(format!("Error: {} relation(s) not found in graph. Please verify exact relation properties using read_graph.", missing_count));
|
||||
return Err(format!(
|
||||
"Error: {} relation(s) not found in graph. Please verify exact relation properties using read_graph.",
|
||||
missing_count
|
||||
));
|
||||
}
|
||||
Ok("Relations deleted".to_string())
|
||||
}
|
||||
@@ -536,7 +561,10 @@ impl McpTool for CondenseEntityHandler {
|
||||
}
|
||||
});
|
||||
if missing {
|
||||
return Err(format!("Error: Entity '{}' not found. Please verify the exact entity name using search_nodes.", req.entity_name));
|
||||
return Err(format!(
|
||||
"Error: Entity '{}' not found. Please verify the exact entity name using search_nodes.",
|
||||
req.entity_name
|
||||
));
|
||||
}
|
||||
Ok("Entity condensed".to_string())
|
||||
}
|
||||
@@ -588,7 +616,10 @@ impl McpTool for MergeEntitiesHandler {
|
||||
});
|
||||
});
|
||||
if missing {
|
||||
return Err(format!("Error: Source entity '{}' not found. Please verify the exact entity name using search_nodes.", req.source_entity));
|
||||
return Err(format!(
|
||||
"Error: Source entity '{}' not found. Please verify the exact entity name using search_nodes.",
|
||||
req.source_entity
|
||||
));
|
||||
}
|
||||
Ok("Entities merged".to_string())
|
||||
}
|
||||
@@ -691,7 +722,7 @@ mod tests {
|
||||
});
|
||||
let res = handler.execute(args, state.clone()).await.unwrap();
|
||||
assert_eq!(res, "Relations created");
|
||||
|
||||
|
||||
// Test semantic LLM schema feedback (User request)
|
||||
let bad_args = json!({
|
||||
"relations": [
|
||||
|
||||
Reference in new issue
Block a user