//! Errors raised by `klieo-flows`.

use thiserror::Error;

/// Errors returned by [`crate::flow::Flow::run`] and its concrete impls.
#[derive(Debug, Error)]
pub enum FlowError {
    /// An underlying [`klieo_core::Agent`] returned an error. Stringly
    /// typed because `Agent::Error` is associated and not erasable.
    #[error("agent error: {0}")]
    Agent(String),

    /// Marshalling between typed I/O and `serde_json::Value` failed.
    #[error("json marshalling: {0}")]
    Json(#[from] serde_json::Error),

    /// [`crate::loop_flow::LoopFlow`] exceeded `max_iters` or its predicate
    /// returned `LoopVerdict::Failed`.
    #[error("loop terminated: {reason} (iter {iter})")]
    Loop {
        /// Human-readable reason.
        reason: String,
        /// Iteration count at termination.
        iter: u32,
    },

    /// [`crate::graph::GraphFlow`] hit a cycle, missing node, or missing edge.
    #[error("graph error: {0}")]
    Graph(String),

    /// Underlying bus surfaced a transient failure during a flow.
    #[error("bus error: {0}")]
    Bus(#[from] klieo_core::error::BusError),
}
