84 lines
2.5 KiB
Rust
84 lines
2.5 KiB
Rust
|
|
//! 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<String>,
|
||
|
|
},
|
||
|
|
|
||
|
|
/// 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<String>, reason: impl Into<String>) -> Self {
|
||
|
|
Self::OpBody {
|
||
|
|
op_id: op_id.into(),
|
||
|
|
reason: reason.into(),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|