use thiserror::Error;
#[derive(Debug, Error)]
pub enum KumoError {
#[error("fetch error: {0}")]
Fetch(#[from] reqwest::Error),
#[error("parse error — {context}: {source}")]
Parse {
context: String,
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
#[error("store error — {context}: {source}")]
Store {
context: String,
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
#[error("invalid URL: {0}")]
InvalidUrl(String),
#[error("max crawl depth exceeded")]
DepthExceeded,
#[error("domain not allowed: {0}")]
DomainNotAllowed(String),
#[error("llm error: {0}")]
Llm(String),
#[error("browser error: {0}")]
Browser(String),
#[error("HTTP {status} from {url}")]
HttpStatus { status: u16, url: String },
}
#[derive(Debug)]
struct Msg(String);
impl std::fmt::Display for Msg {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl std::error::Error for Msg {}
impl KumoError {
pub fn parse(
context: impl Into<String>,
source: impl std::error::Error + Send + Sync + 'static,
) -> Self {
Self::Parse {
context: context.into(),
source: Box::new(source),
}
}
pub fn parse_msg(msg: impl Into<String>) -> Self {
let msg = msg.into();
Self::Parse {
context: msg.clone(),
source: Box::new(Msg(msg)),
}
}
pub fn store(
context: impl Into<String>,
source: impl std::error::Error + Send + Sync + 'static,
) -> Self {
Self::Store {
context: context.into(),
source: Box::new(source),
}
}
pub fn store_msg(msg: impl Into<String>) -> Self {
let msg = msg.into();
Self::Store {
context: msg.clone(),
source: Box::new(Msg(msg)),
}
}
}
#[derive(Debug, Clone)]
pub enum ErrorPolicy {
Skip,
Abort,
Retry(u32),
}