//! Pipeline failure modes — distinguish recoverable user errors from //! invariant violations. use thiserror::Error; use crate::validation::Verdict; /// Failures emitted by the runtime pipeline. #[derive(Debug, Error)] pub enum OpError { /// No operation with the requested id is registered. #[error("operation '{0}' is not registered")] UnknownOperation(String), /// A pre- or post-validator rejected the operation. #[error("validator rejected operation '{op_id}': {verdict:?}")] ValidatorRejected { /// Operation id that was rejected. op_id: String, /// Verdict returned by the rejecting validator. verdict: Verdict, }, /// Loading the precondition slice failed. #[error("precondition load for '{op_id}': {reason}")] PreconditionLoad { /// Operation id whose precondition failed to load. op_id: String, /// Human-readable reason. reason: String, }, /// The op body returned an error. #[error("op body for '{op_id}': {reason}")] OpBody { /// Operation id whose body returned an error. op_id: String, /// Human-readable reason. reason: String, }, /// Render of one of the op's render paths failed. #[error("render '{path}': {reason}")] Render { /// Render path that failed. path: String, /// Human-readable reason. reason: String, }, /// Actor is not permitted to invoke this op. #[error("actor '{actor_id}' not permitted for op '{op_id}' (allowed roles: {allowed:?})")] ActorPolicyDenied { /// Actor id that attempted the op. actor_id: String, /// Operation id whose actor policy denied the call. op_id: String, /// Roles permitted by the op's `actor_policy`. allowed: Vec, }, /// Persisting the signed witness to the oplog failed (`substrate` /// feature). The render of the NCL projection may already have /// succeeded, so the caller must treat state and proof as divergent /// and retry or reconcile. #[error("witness persist for '{op_id}': {reason}")] WitnessPersist { /// Operation id whose witness failed to persist. op_id: String, /// Human-readable reason. reason: String, }, } impl OpError { /// Build an [`OpError::OpBody`] from a generic error message. pub fn body(op_id: impl Into, reason: impl Into) -> Self { Self::OpBody { op_id: op_id.into(), reason: reason.into(), } } }