use vs_protocol::{ErrorCode, ParseError, StateToken};
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum DaemonError {
#[error("protocol parse: {0}")]
Protocol(#[from] ParseError),
#[error("store: {0}")]
Store(#[from] vs_store::StoreError),
#[error("engine: {0}")]
Engine(#[from] vs_engine_webkit::EngineError),
#[error("io: {0}")]
Io(#[from] std::io::Error),
#[error("anyhow: {0}")]
Other(#[from] anyhow::Error),
#[error("stale token: current={current}, reason={reason}")]
StaleToken {
current: StateToken,
reason: &'static str,
},
#[error("no active session")]
NoSession,
#[error("unknown session: {0}")]
UnknownSession(String),
#[error("unknown page: {0}")]
UnknownPage(String),
#[error("unknown ref: {0}")]
UnknownRef(u32),
#[error("bad request: {0}")]
BadRequest(String),
#[error("unsupported on this engine: {primitive} ({engine})")]
Unsupported {
engine: &'static str,
primitive: &'static str,
},
}
impl DaemonError {
#[must_use]
pub fn wire(&self) -> (ErrorCode, Vec<String>) {
match self {
Self::StaleToken { current, reason } => (
ErrorCode::StaleToken,
vec![current.to_string(), (*reason).to_string()],
),
Self::NoSession => (ErrorCode::BadRequest, vec!["no_session".into()]),
Self::UnknownSession(id) => (ErrorCode::NotFound, vec![format!("session={id}")]),
Self::UnknownPage(id) => (ErrorCode::NotFound, vec![format!("page={id}")]),
Self::UnknownRef(r) => (ErrorCode::NotFound, vec![format!("ref={r}")]),
Self::BadRequest(msg) => (ErrorCode::BadRequest, vec![msg.clone()]),
Self::Unsupported { engine, primitive }
| Self::Engine(vs_engine_webkit::EngineError::Unsupported { engine, primitive }) => (
ErrorCode::EngineUnsupported,
vec![(*primitive).to_string(), (*engine).to_string()],
),
Self::Engine(vs_engine_webkit::EngineError::Timeout { primitive, budget }) => (
ErrorCode::Timeout,
vec![
format!("{}ms", budget.as_millis()),
(*primitive).to_string(),
],
),
Self::Engine(vs_engine_webkit::EngineError::NotFound { kind, id }) => {
(ErrorCode::NotFound, vec![format!("{kind}={id}")])
}
Self::Engine(vs_engine_webkit::EngineError::Crashed) => {
(ErrorCode::EngineCrash, vec![])
}
Self::Engine(_) => (ErrorCode::BadRequest, vec![format!("engine: {self}")]),
Self::Protocol(_) => (ErrorCode::BadRequest, vec![format!("{self}")]),
Self::Store(_) | Self::Io(_) | Self::Other(_) => {
(ErrorCode::BadRequest, vec![format!("{self}")])
}
}
}
}
pub type Result<T> = std::result::Result<T, DaemonError>;