fix(mcp): prevent internal handler serialization errors from being silently discarded or defaulting to empty strings
This commit is contained in:
1 parent
8f32a09399
commit
febd48c65d
5 files changed
+12
-12
No files matched your search
@@ -86,7 +86,7 @@ pub async fn handle_socket(socket: WebSocket, state: Arc<AppState>, _client_type
|
|||||||
if let Ok(payload) = serde_json::from_str::<serde_json::Value>(&text) {
|
if let Ok(payload) = serde_json::from_str::<serde_json::Value>(&text) {
|
||||||
// Process MCP request
|
// Process MCP request
|
||||||
if let Some(response) = handler.handle_request(payload).await {
|
if let Some(response) = handler.handle_request(payload).await {
|
||||||
let res_str = serde_json::to_string(&response).unwrap_or_default();
|
let res_str = serde_json::to_string(&response).unwrap_or_else(|e| format!(r#"{{\"jsonrpc\":\"2.0\",\"id\":null,\"error\":{{\"code\":-32603,\"message\":\"{}\"}}}}"#, e));
|
||||||
let tx_opt = state_clone
|
let tx_opt = state_clone
|
||||||
.clients
|
.clients
|
||||||
.read()
|
.read()
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ impl McpTool for ReadEnvFingerprintHandler {
|
|||||||
.env_fingerprints
|
.env_fingerprints
|
||||||
.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).map_err(|e| e.to_string())?;
|
||||||
Ok(data)
|
Ok(data)
|
||||||
} else {
|
} else {
|
||||||
Ok("{}".to_string())
|
Ok("{}".to_string())
|
||||||
|
|||||||
@@ -353,7 +353,7 @@ impl McpTool for ReadGraphHandler {
|
|||||||
|
|
||||||
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 req: ReadGraphTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
|
let req: ReadGraphTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||||
let data = state.read_graph(|full| {
|
let data = state.read_graph(|full| -> Result<String, String> {
|
||||||
if let Some(ns) = req.namespace {
|
if let Some(ns) = req.namespace {
|
||||||
let mut filtered = BorrowedGraph::default();
|
let mut filtered = BorrowedGraph::default();
|
||||||
for (k, v) in &full.entities {
|
for (k, v) in &full.entities {
|
||||||
@@ -366,11 +366,11 @@ impl McpTool for ReadGraphHandler {
|
|||||||
filtered.relations.push(r);
|
filtered.relations.push(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
serde_json::to_string(&filtered).unwrap_or_default()
|
serde_json::to_string(&filtered).map_err(|e| e.to_string())
|
||||||
} else {
|
} else {
|
||||||
serde_json::to_string(full).unwrap_or_default()
|
serde_json::to_string(full).map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
});
|
})?;
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -396,7 +396,7 @@ impl McpTool for SearchNodesHandler {
|
|||||||
vec![]
|
vec![]
|
||||||
};
|
};
|
||||||
|
|
||||||
let data = state.read_graph(|full| {
|
let data = state.read_graph(|full| -> Result<String, String> {
|
||||||
let mut result = BorrowedGraph::default();
|
let mut result = BorrowedGraph::default();
|
||||||
for (id, doc_type, _, _, _) in &matches {
|
for (id, doc_type, _, _, _) in &matches {
|
||||||
if doc_type == "entity"
|
if doc_type == "entity"
|
||||||
@@ -425,7 +425,7 @@ impl McpTool for OpenNodesHandler {
|
|||||||
|
|
||||||
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 req: OpenNodesTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
|
let req: OpenNodesTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||||
let data = state.read_graph(|full| {
|
let data = state.read_graph(|full| -> Result<String, String> {
|
||||||
let targets: HashSet<&str> = req.names.iter().map(|s| s.as_str()).collect();
|
let targets: HashSet<&str> = req.names.iter().map(|s| s.as_str()).collect();
|
||||||
let mut result = BorrowedGraph::default();
|
let mut result = BorrowedGraph::default();
|
||||||
let mut connected: HashSet<&str> = HashSet::new();
|
let mut connected: HashSet<&str> = HashSet::new();
|
||||||
@@ -650,7 +650,7 @@ impl McpTool for FindOrphansHandler {
|
|||||||
.cloned()
|
.cloned()
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
});
|
});
|
||||||
let data = serde_json::to_string(&orphans).unwrap_or_default();
|
let data = serde_json::to_string(&orphans).map_err(|e| e.to_string())?;
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -276,8 +276,8 @@ impl McpTool for ReadPreferencesHandler {
|
|||||||
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
|
||||||
.prefs
|
.prefs
|
||||||
.read_with(|prefs| serde_json::to_string(prefs).unwrap_or_default());
|
.read_with(|prefs| serde_json::to_string(prefs).map_err(|e| e.to_string()));
|
||||||
Ok(data)
|
data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@ impl<T: DeserializeOwned + Default + Serialize + Clone + Send + Sync + 'static>
|
|||||||
let key_inner = key_clone.clone();
|
let key_inner = key_clone.clone();
|
||||||
let json_data = {
|
let json_data = {
|
||||||
let lock = cache_clone.read().unwrap_or_else(|e| e.into_inner());
|
let lock = cache_clone.read().unwrap_or_else(|e| e.into_inner());
|
||||||
serde_json::to_vec(&*lock).ok()
|
serde_json::to_vec(&*lock).map_err(|e| tracing::error!("Failed to serialize memory store: {}", e)).ok()
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(json_data) = json_data {
|
if let Some(json_data) = json_data {
|
||||||
|
|||||||
Reference in new issue
Block a user