Initial commit
This commit is contained in:
77
src-tauri/src/acp/error.rs
Normal file
77
src-tauri/src/acp/error.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum AcpError {
|
||||
#[error("agent process failed to spawn: {0}")]
|
||||
SpawnFailed(String),
|
||||
#[error("connection not found: {0}")]
|
||||
ConnectionNotFound(String),
|
||||
#[error("ACP protocol error: {0}")]
|
||||
Protocol(String),
|
||||
#[error("agent process exited unexpectedly")]
|
||||
ProcessExited,
|
||||
#[allow(dead_code)]
|
||||
#[error("conversation error: {0}")]
|
||||
Conversation(String),
|
||||
#[error("binary download failed: {0}")]
|
||||
DownloadFailed(String),
|
||||
#[allow(dead_code)]
|
||||
#[error("agent not found: {0}")]
|
||||
AgentNotFound(String),
|
||||
#[error("platform not supported: {0}")]
|
||||
PlatformNotSupported(String),
|
||||
}
|
||||
|
||||
impl AcpError {
|
||||
pub fn protocol(raw: impl Into<String>) -> Self {
|
||||
let raw = raw.into();
|
||||
let sanitized = sanitize_protocol_message(&raw);
|
||||
|
||||
if is_executable_format_error(&sanitized) {
|
||||
return Self::Protocol(
|
||||
"Agent executable appears incompatible or corrupted. Please retry to re-download it."
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
Self::Protocol(sanitized)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for AcpError {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn sanitize_protocol_message(raw: &str) -> String {
|
||||
let without_spawned_at = regex::Regex::new(r#"\s*,?\s*"spawned_at"\s*:\s*"[^"]*"\s*,?"#)
|
||||
.ok()
|
||||
.map(|re| re.replace_all(raw, "").into_owned())
|
||||
.unwrap_or_else(|| raw.to_string());
|
||||
|
||||
let without_dangling_comma = regex::Regex::new(r#",\s*([}\]])"#)
|
||||
.ok()
|
||||
.map(|re| re.replace_all(&without_spawned_at, "$1").into_owned())
|
||||
.unwrap_or(without_spawned_at);
|
||||
|
||||
regex::Regex::new(r#"/(?:Users|home)/[^"\s]+"#)
|
||||
.ok()
|
||||
.map(|re| {
|
||||
re.replace_all(&without_dangling_comma, "<local-path>")
|
||||
.into_owned()
|
||||
})
|
||||
.unwrap_or(without_dangling_comma)
|
||||
}
|
||||
|
||||
fn is_executable_format_error(message: &str) -> bool {
|
||||
let lowered = message.to_lowercase();
|
||||
lowered.contains("malformed mach-o file")
|
||||
|| lowered.contains("exec format error")
|
||||
|| lowered.contains("bad cpu type in executable")
|
||||
|| lowered.contains("not a valid win32 application")
|
||||
|| lowered.contains("is not a valid application for this os platform")
|
||||
}
|
||||
Reference in New Issue
Block a user