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}