refactor(mcp): collapse repeated failure-arm triplet into reply_err helper

This commit is contained in:
müde 2026-07-05 22:05:06 +02:00
commit 543177ed74

View file

@ -180,6 +180,20 @@ fn write_status_file(text: &str) -> Result<(), String> {
result.map_err(|e| format!("set_status write failed: {e}"))
}
/// Render the three identical failure arms every data-returning tool handler
/// repeats: a broker `Err` → `"{tool} failed: {m}"`, an unexpected `Ok` variant
/// → `"{tool} unexpected response: …"`, and a transport error → `"{tool}
/// transport error: …"`. Handlers match their own happy-path variant and route
/// everything else here via a catch-all arm (`other => reply_err(other, tool)`),
/// so the triplet lives in exactly one place.
fn reply_err(resp: Result<SocketReply, anyhow::Error>, tool: &str) -> String {
match resp {
Ok(SocketReply::Err(m)) => format!("{tool} failed: {m}"),
Ok(other) => format!("{tool} unexpected response: {other:?}"),
Err(e) => format!("{tool} transport error: {e:#}"),
}
}
/// Format helper for "send-like" tools (anything that expects an `Ok`).
/// `tool` and `ok_msg` only appear in the result string; they don't change
/// behavior.
@ -187,9 +201,7 @@ fn write_status_file(text: &str) -> Result<(), String> {
pub fn format_ack(resp: Result<SocketReply, anyhow::Error>, tool: &str, ok_msg: String) -> String {
match resp {
Ok(SocketReply::Ok) => ok_msg,
Ok(SocketReply::Err(m)) => format!("{tool} failed: {m}"),
Ok(other) => format!("{tool} unexpected response: {other:?}"),
Err(e) => format!("{tool} transport error: {e:#}"),
other => reply_err(other, tool),
}
}
@ -205,13 +217,16 @@ pub fn format_ack(resp: Result<SocketReply, anyhow::Error>, tool: &str, ok_msg:
/// per-message redelivery banners included.
#[must_use]
pub fn format_recv(resp: Result<SocketReply, anyhow::Error>, waited: bool) -> String {
match resp {
Ok(SocketReply::Messages(m)) => render_recv_messages(&m, waited),
other => reply_err(other, "recv"),
}
}
/// Render the popped-message payload of a successful `recv` (see `format_recv`
/// for the empty/single/batch shapes).
fn render_recv_messages(messages: &[hive_sh4re::DeliveredMessage], waited: bool) -> String {
use std::fmt::Write as _;
let messages = match resp {
Ok(SocketReply::Messages(m)) => m,
Ok(SocketReply::Err(m)) => return format!("recv failed: {m}"),
Ok(other) => return format!("recv unexpected response: {other:?}"),
Err(e) => return format!("recv transport error: {e:#}"),
};
if messages.is_empty() {
return if waited {
format!("(empty){IDLE_WAIT_HINT}")
@ -536,9 +551,7 @@ pub fn format_agent_meta(resp: Result<SocketReply, anyhow::Error>) -> String {
}
out
}
Ok(SocketReply::Err(m)) => format!("get_agent_meta failed: {m}"),
Ok(other) => format!("get_agent_meta unexpected response: {other:?}"),
Err(e) => format!("get_agent_meta transport error: {e:#}"),
other => reply_err(other, "get_agent_meta"),
}
}
@ -761,9 +774,7 @@ impl AgentServer {
"question queued (id={id}); answer will arrive as a system \
`question_answered` event in your inbox"
),
Ok(SocketReply::Err(m)) => format!("ask failed: {m}"),
Ok(other) => format!("ask unexpected response: {other:?}"),
Err(e) => format!("ask transport error: {e:#}"),
other => reply_err(other, "ask"),
};
annotate_retries(s, retries)
})
@ -850,9 +861,7 @@ impl AgentServer {
Ok(SocketReply::Acked(count)) => {
format!("acked {count} message(s) up to id {}", args.up_to)
}
Ok(SocketReply::Err(m)) => format!("ack_until failed: {m}"),
Ok(other) => format!("ack_until unexpected response: {other:?}"),
Err(e) => format!("ack_until transport error: {e:#}"),
other => reply_err(other, "ack_until"),
};
annotate_retries(rendered, retries)
})
@ -883,21 +892,7 @@ impl AgentServer {
// Extract the vec so we can augment before rendering.
let mut loose_ends = match resp {
Ok(SocketReply::LooseEnds(t)) => t,
Ok(SocketReply::Err(m)) => {
return annotate_retries(format!("get_loose_ends failed: {m}"), retries);
}
Ok(other) => {
return annotate_retries(
format!("get_loose_ends unexpected response: {other:?}"),
retries,
);
}
Err(e) => {
return annotate_retries(
format!("get_loose_ends transport error: {e:#}"),
retries,
);
}
other => return annotate_retries(reply_err(other, "get_loose_ends"), retries),
};
// Prepend matrix unread entry for self-queries only (can't
// reach another agent's matrix daemon from here).
@ -1039,9 +1034,7 @@ impl AgentServer {
full_name,
clone_url,
}) => format!("created repo {full_name} — clone: {clone_url}"),
Ok(SocketReply::Err(m)) => format!("create_repo failed: {m}"),
Ok(other) => format!("create_repo unexpected response: {other:?}"),
Err(e) => format!("create_repo transport error: {e:#}"),
other => reply_err(other, "create_repo"),
};
annotate_retries(s, retries)
})
@ -1212,9 +1205,7 @@ impl AgentServer {
.join("\n")
}
}
Ok(SocketReply::Err(m)) => format!("list_containers failed: {m}"),
Ok(other) => format!("list_containers unexpected response: {other:?}"),
Err(e) => format!("list_containers transport error: {e:#}"),
other => reply_err(other, "list_containers"),
};
annotate_retries(body, retries)
})
@ -1255,9 +1246,7 @@ impl AgentServer {
.await;
let result = match resp {
Ok(SocketReply::HostJournal(content)) => content,
Ok(SocketReply::Err(m)) => format!("get_host_journal failed: {m}"),
Ok(other) => format!("get_host_journal unexpected response: {other:?}"),
Err(e) => format!("get_host_journal transport error: {e:#}"),
other => reply_err(other, "get_host_journal"),
};
annotate_retries(result, retries)
})
@ -1388,9 +1377,7 @@ impl AgentServer {
content
}
}
Ok(SocketReply::Err(m)) => format!("get_logs failed: {m}"),
Ok(other) => format!("get_logs unexpected response: {other:?}"),
Err(e) => format!("get_logs transport error: {e:#}"),
other => reply_err(other, "get_logs"),
};
annotate_retries(s, retries)
})
@ -1578,9 +1565,7 @@ impl AgentServer {
let body = match resp {
Ok(SocketReply::Schedules(schedules)) => serde_json::to_string(&schedules)
.unwrap_or_else(|e| format!("list_schedules: serialise: {e:#}")),
Ok(SocketReply::Err(m)) => format!("list_schedules: {m}"),
Ok(other) => format!("list_schedules unexpected response: {other:?}"),
Err(e) => format!("list_schedules transport error: {e:#}"),
other => reply_err(other, "list_schedules"),
};
annotate_retries(body, retries)
})