use crate::common::error_codes;
use crate::common::error_codes::ErrorCategory;
use std::error::Error as StdError;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum DaemonError {
#[error("Failed to bind socket ({operation}): {source}")]
SocketBind {
operation: &'static str,
#[source]
source: Box<dyn StdError + Send + Sync>,
},
#[error("Another daemon instance is already running")]
AlreadyRunning,
#[error("Failed to acquire lock ({operation}): {source}")]
LockFailed {
operation: &'static str,
#[source]
source: Box<dyn StdError + Send + Sync>,
},
#[error("Failed to setup signal handler: {0}")]
SignalSetup(String),
#[error("Failed to create thread pool: {0}")]
ThreadPool(String),
#[error("Failed to initialize daemon during {operation}: {source}")]
Startup {
operation: &'static str,
#[source]
source: Box<dyn StdError + Send + Sync>,
},
}
impl DaemonError {
pub fn code(&self) -> i32 {
error_codes::DAEMON_ERROR
}
pub fn category(&self) -> ErrorCategory {
ErrorCategory::External
}
pub fn suggestion(&self) -> String {
match self {
DaemonError::SocketBind { .. } => {
"Check that the Unix socket directory is writable. Inspect the active socket path with 'agent-tui env' and remove any stale socket file.".to_string()
}
DaemonError::AlreadyRunning => {
"Another daemon is running. Use 'agent-tui sessions' to connect or kill existing daemon."
.to_string()
}
DaemonError::LockFailed { .. } => {
"Lock file issue. Inspect the active socket path with 'agent-tui env' and remove the matching stale .lock file if needed.".to_string()
}
DaemonError::SignalSetup(_) => {
"Signal handler setup failed. Check system signal configuration.".to_string()
}
DaemonError::ThreadPool(_) => {
"Thread pool creation failed. Check system thread limits (ulimit -u).".to_string()
}
DaemonError::Startup { .. } => {
"Daemon startup could not restore or verify session state. Inspect the session store path from 'agent-tui env' and fix any stale or invalid files before retrying.".to_string()
}
}
}
pub fn is_retryable(&self) -> bool {
matches!(self, DaemonError::LockFailed { .. })
}
}