use serde::{Deserialize, Serialize};
use super::session_id::SessionId;
use super::state::ExecutionStateTag;
use crate::FeedError;
#[derive(Debug, thiserror::Error, Serialize, Deserialize)]
pub enum SpawnError {
#[error("engine error: {0}")]
Engine(String),
#[error("invalid spec: {0}")]
InvalidSpec(String),
}
#[derive(Debug, thiserror::Error, Serialize, Deserialize)]
pub enum StateError {
#[error("session not found: {0}")]
NotFound(SessionId),
}
#[derive(Debug, thiserror::Error, Serialize, Deserialize)]
pub enum ResumeError {
#[error("session not found: {0}")]
NotFound(SessionId),
#[error("session is not paused; actual state: {actual_tag:?}")]
NotPaused {
actual_tag: ExecutionStateTag,
},
#[error("session is already cancelled")]
AlreadyCancelled,
#[error("feed error: {0}")]
FeedError(String),
}
impl From<FeedError> for ResumeError {
fn from(e: FeedError) -> Self {
Self::FeedError(e.to_string())
}
}
#[derive(Debug, thiserror::Error, Serialize, Deserialize)]
pub enum CancelError {
#[error("session not found: {0}")]
NotFound(SessionId),
}
#[derive(Debug, thiserror::Error, Serialize, Deserialize)]
pub enum ObserveError {
#[error("session not found: {0}")]
NotFound(SessionId),
}
#[derive(Debug, thiserror::Error, Serialize, Deserialize)]
pub enum AwaitError {
#[error("session not found: {0}")]
NotFound(SessionId),
#[error("join error: {0}")]
Joined(String),
}
#[derive(Debug, thiserror::Error, Serialize, Deserialize)]
pub enum ObserverRecvError {
#[error("observer lagged by {0} events")]
Lagged(u64),
#[error("broadcast channel closed")]
Closed,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::query::QueryId;
#[test]
fn resume_error_serde_roundtrip() {
let not_found = ResumeError::NotFound(SessionId::new("sess-1".into()));
let json = serde_json::to_string(¬_found).expect("serialize NotFound");
let _: ResumeError = serde_json::from_str(&json).expect("deserialize NotFound");
let not_paused = ResumeError::NotPaused {
actual_tag: ExecutionStateTag::Running,
};
let json = serde_json::to_string(¬_paused).expect("serialize NotPaused");
let _: ResumeError = serde_json::from_str(&json).expect("deserialize NotPaused");
let already_cancelled = ResumeError::AlreadyCancelled;
let json = serde_json::to_string(&already_cancelled).expect("serialize AlreadyCancelled");
let _: ResumeError = serde_json::from_str(&json).expect("deserialize AlreadyCancelled");
let feed_err = FeedError::UnknownQuery(QueryId::parse("q1"));
let resume_err: ResumeError = feed_err.into();
let json = serde_json::to_string(&resume_err).expect("serialize FeedError variant");
let _: ResumeError = serde_json::from_str(&json).expect("deserialize FeedError variant");
}
#[test]
fn observer_recv_error_serde_roundtrip() {
let lagged = ObserverRecvError::Lagged(42);
let json = serde_json::to_string(&lagged).expect("serialize Lagged");
let _: ObserverRecvError = serde_json::from_str(&json).expect("deserialize Lagged");
let closed = ObserverRecvError::Closed;
let json = serde_json::to_string(&closed).expect("serialize Closed");
let _: ObserverRecvError = serde_json::from_str(&json).expect("deserialize Closed");
}
#[test]
fn all_error_enums_display() {
let e = SpawnError::InvalidSpec("bad field".into());
assert!(e.to_string().contains("bad field"));
let e = StateError::NotFound(SessionId::new("s1".into()));
assert!(e.to_string().contains("s1"));
let e = CancelError::NotFound(SessionId::new("s2".into()));
assert!(e.to_string().contains("s2"));
let e = ObserveError::NotFound(SessionId::new("s3".into()));
assert!(e.to_string().contains("s3"));
let e = AwaitError::Joined("panic message".into());
assert!(e.to_string().contains("panic message"));
}
}