Skip to main content

agent_effects/
error.rs

1//! Infrastructure errors.
2//!
3//! These are failures of the runtime itself: storage, configuration,
4//! serialization. What happened to an effect, including "unknown", is an
5//! [`EffectOutcome`](crate::EffectOutcome), never a `RuntimeError`.
6
7use crate::id::{EffectId, IdentityError};
8use crate::kind::EffectKind;
9use crate::store::StoreError;
10
11/// Why the runtime could not process an effect.
12#[derive(Debug, thiserror::Error)]
13#[non_exhaustive]
14pub enum RuntimeError {
15    /// The effect name or logical key was invalid.
16    #[error("invalid effect identity: {0}")]
17    Identity(#[from] IdentityError),
18
19    /// The key was used before with a different input. Returning the earlier
20    /// effect's result would answer a question nobody asked.
21    #[error("effect {id} was recorded with a different input")]
22    InputMismatch {
23        /// The existing effect.
24        id: EffectId,
25    },
26
27    /// The key was used before with a different [`EffectKind`].
28    #[error("effect {id} was recorded as {stored:?}, not {requested:?}")]
29    KindMismatch {
30        /// The existing effect.
31        id: EffectId,
32        /// The kind on record.
33        stored: EffectKind,
34        /// The kind of this call.
35        requested: EffectKind,
36    },
37
38    /// The input could not be serialized.
39    #[error("could not serialize the effect input: {0}")]
40    Input(#[source] serde_json::Error),
41
42    /// A committed effect's stored output does not deserialize into the
43    /// requested type, e.g. because the type changed since it was recorded.
44    #[error(
45        "effect {id} committed, but its stored output does not match the requested type: {source}"
46    )]
47    Output {
48        /// The committed effect.
49        id: EffectId,
50        /// The deserialization error.
51        #[source]
52        source: serde_json::Error,
53    },
54
55    /// The runtime's risk policy requires something the effect lacks, so
56    /// it was refused before anything was recorded.
57    #[error("effect `{key}` violates the risk policy: it requires {requirement}")]
58    PolicyViolation {
59        /// The effect's `name:key`.
60        key: String,
61        /// What the policy requires, e.g. `verification`.
62        requirement: &'static str,
63    },
64
65    /// No effect has this name and key.
66    #[error("no effect `{key}` exists")]
67    NoSuchEffect {
68        /// The effect's `name:key`.
69        key: String,
70    },
71
72    /// The handler is registered without `.compensable()`, so its effects
73    /// cannot be compensated.
74    #[error("the handler for effect `{name}` is not registered as compensable")]
75    NotCompensable {
76        /// The effect name.
77        name: &'static str,
78    },
79
80    /// No handler of the submitted type is registered under its name.
81    #[error("no handler registered for effect `{name}`")]
82    NotRegistered {
83        /// The effect name.
84        name: &'static str,
85    },
86
87    /// A stored input no longer deserializes into the handler's input type,
88    /// e.g. because the type changed since the effect was recorded.
89    #[error("effect {id}'s stored input does not match its handler's input type: {source}")]
90    StoredInput {
91        /// The effect.
92        id: EffectId,
93        /// The deserialization error.
94        #[source]
95        source: serde_json::Error,
96    },
97
98    /// The store failed. If this happens after the action ran, the effect
99    /// stays in doubt and recovery will treat its outcome as unknown.
100    #[error(transparent)]
101    Store(#[from] StoreError),
102
103    /// The runtime's own task failed (a bug in `agent-effects`).
104    #[error("effect task failed: {0}")]
105    Internal(String),
106}