use thiserror::Error;
#[derive(Debug, Error)]
pub enum AudioError {
#[error("no suitable audio device found")]
NoDevice,
#[error("failed to negotiate audio stream config: {0}")]
StreamConfig(String),
#[error("failed to build audio stream: {0}")]
StreamBuild(String),
#[error("resampling failed: {0}")]
Resample(String),
}
#[derive(Debug, Error)]
pub enum VadError {
#[error("failed to load VAD model: {0}")]
ModelLoad(String),
#[error("VAD inference failed: {0}")]
Inference(String),
#[error("VAD frames must be {expected} samples, got {actual}")]
BadFrameLen {
expected: usize,
actual: usize,
},
}
#[derive(Debug, Error)]
pub enum SttError {
#[error("failed to load STT model: {0}")]
ModelLoad(String),
#[error("transcription failed: {0}")]
Transcribe(String),
#[error("STT worker thread is gone")]
WorkerGone,
}
#[derive(Debug, Error)]
pub enum LlmError {
#[error("LLM HTTP error: {0}")]
Http(#[from] reqwest::Error),
#[error("LLM SSE stream error: {0}")]
Sse(String),
#[error("LLM API returned status {status}: {body}")]
Api {
status: u16,
body: String,
},
#[error("LLM request cancelled")]
Cancelled,
}
#[derive(Debug, Error)]
pub enum TtsError {
#[error("failed to load TTS model: {0}")]
ModelLoad(String),
#[error("phonemization failed: {0}")]
Phonemize(String),
#[error("TTS inference failed: {0}")]
Inference(String),
#[error("TTS voices unavailable: {0}")]
MissingVoices(String),
}
#[derive(Debug, Error)]
pub enum SkadooshError {
#[error(transparent)]
Audio(#[from] AudioError),
#[error(transparent)]
Vad(#[from] VadError),
#[error(transparent)]
Stt(#[from] SttError),
#[error(transparent)]
Llm(#[from] LlmError),
#[error(transparent)]
Tts(#[from] TtsError),
#[error(transparent)]
Other(#[from] anyhow::Error),
}
pub type Result<T> = std::result::Result<T, SkadooshError>;