Refactor: Migrate unwrap calls to AppError in MCP handlers

This commit is contained in:
Riz Ashraf committed 2026-09-30 21:02:50 +01:00
1 parent 4e1a633dbd
commit 0e866f2465
12 files changed
+276 -326

No files matched your search

+20 -25
View File
@@ -19,7 +19,7 @@ impl McpTool for AddStickyNoteHandler {
crate::mcp::tool_def::<AddStickyNoteTool>("add_sticky_note", "Execute add_sticky_note")
}
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: AddStickyNoteTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
state.sticky.modify(|notes| {
notes.push(StickyNote {
@@ -47,10 +47,10 @@ 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>) -> crate::error::Result<String> {
let data = state
.sticky
.read_with(|s| serde_json::to_string(s).map_err(|e| e.to_string()))?;
.read_with(|s| Ok::<String, crate::error::AppError>(serde_json::to_string(s)?))?;
Ok(data)
}
}
@@ -70,7 +70,7 @@ impl McpTool for DeleteStickyNoteHandler {
)
}
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: DeleteStickyNoteTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
let mut success = false;
state.sticky.modify(|notes| {
@@ -82,7 +82,7 @@ impl McpTool for DeleteStickyNoteHandler {
if success {
Ok("Sticky note deleted.".to_string())
} else {
Err("Invalid sticky note index.".to_string())
Err(crate::error::AppError::Internal("Invalid sticky note index.".to_string()))
}
}
}
@@ -102,7 +102,7 @@ impl McpTool for ClearStickyNotesHandler {
)
}
async fn execute(&self, _args: Value, state: Arc<MemoryState>) -> Result<String, String> {
async fn execute(&self, _args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
state.sticky.modify(|notes| {
notes.clear();
});
@@ -125,7 +125,7 @@ impl McpTool for LeaveHandoffMemoHandler {
)
}
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: LeaveHandoffMemoTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
state.handoff_memos.modify(|memos| {
memos.push(crate::models::HandoffMemo {
@@ -156,7 +156,7 @@ impl McpTool for ReadHandoffMemosHandler {
)
}
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: ReadHandoffMemosTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
let data = state.handoff_memos.read_with(|items| {
let filtered: Vec<_> = items
@@ -169,7 +169,7 @@ impl McpTool for ReadHandoffMemosHandler {
}
})
.collect();
serde_json::to_string(&filtered).map_err(|e| e.to_string())
Ok::<String, crate::error::AppError>(serde_json::to_string(&filtered)?)
})?;
Ok(data)
}
@@ -190,7 +190,7 @@ impl McpTool for ClearHandoffMemosHandler {
)
}
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: ClearHandoffMemosTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
let ids: HashSet<_> = req.ids.into_iter().collect();
state
@@ -215,7 +215,7 @@ impl McpTool for AddSessionSummaryHandler {
)
}
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: AddSessionSummaryTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
state.session_summaries.modify(|summaries| {
summaries.push(crate::models::SessionSummary {
@@ -244,7 +244,7 @@ impl McpTool for GenerateStandupReportHandler {
)
}
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: GenerateStandupReportTool =
serde_json::from_value(args).map_err(|e| e.to_string())?;
let cutoff = crate::handlers::utils::now_secs().saturating_sub(req.hours_lookback * 3600);
@@ -280,25 +280,23 @@ mod tests {
"content": "Buy milk",
});
let res = add_handler.execute(args, state.clone()).await.unwrap();
let res = add_handler.execute(args, state.clone()).await.map_err(|e| crate::error::AppError::Internal(e.to_string()))?;
assert!(res.contains("Sticky note added"));
let read_handler = ReadStickyNotesHandler;
let res2 = read_handler
.execute(json!({}), state.clone())
.await
.unwrap();
.await.map_err(|e| crate::error::AppError::Internal(e.to_string()))?;
assert!(res2.contains("Buy milk"));
let delete_handler = DeleteStickyNoteHandler;
let args2 = json!({"index": 1});
let res3 = delete_handler.execute(args2, state.clone()).await.unwrap();
let res3 = delete_handler.execute(args2, state.clone()).await.map_err(|e| crate::error::AppError::Internal(e.to_string()))?;
assert_eq!(res3, "Sticky note deleted.");
let res4 = read_handler
.execute(json!({}), state.clone())
.await
.unwrap();
.await.map_err(|e| crate::error::AppError::Internal(e.to_string()))?;
assert!(!res4.contains("Buy milk"));
}
@@ -314,14 +312,13 @@ mod tests {
"namespace": "global"
});
let res = handoff_handler.execute(args, state.clone()).await.unwrap();
let res = handoff_handler.execute(args, state.clone()).await.map_err(|e| crate::error::AppError::Internal(e.to_string()))?;
assert_eq!(res, "Handoff memo left");
let read_handoff = ReadHandoffMemosHandler;
let res2 = read_handoff
.execute(json!({"namespace": "global"}), state.clone())
.await
.unwrap();
.await.map_err(|e| crate::error::AppError::Internal(e.to_string()))?;
assert!(res2.contains("Finished implementing graph tests"));
let summary_handler = AddSessionSummaryHandler;
@@ -331,8 +328,7 @@ mod tests {
});
let res3 = summary_handler
.execute(args_sum, state.clone())
.await
.unwrap();
.await.map_err(|e| crate::error::AppError::Internal(e.to_string()))?;
assert_eq!(res3, "Session summary added");
let standup_handler = GenerateStandupReportHandler;
@@ -341,8 +337,7 @@ mod tests {
json!({"namespace": "global", "hours_lookback": 24}),
state.clone(),
)
.await
.unwrap();
.await.map_err(|e| crate::error::AppError::Internal(e.to_string()))?;
assert!(!res4.is_empty());
}
}