1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use thiserror::Error;
/// Whether retrying an operation is safe.
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[non_exhaustive]
pub enum RetrySafety {
/// The same operation can be retried safely.
Safe,
/// Retry is safe only when the external system honors an idempotency key.
RequiresIdempotency,
/// Visible output has been emitted, so retry may duplicate output.
UnsafeAfterVisibleOutput,
/// An external side effect may already have occurred.
UnsafeAfterSideEffect,
/// Safety cannot be determined.
Unknown,
}
/// A normalized run failure category.
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[non_exhaustive]
pub enum RunErrorKind {
/// Input or configuration is invalid.
InvalidInput,
/// A required capability was not granted.
CapabilityDenied,
/// A resource budget was exhausted.
BudgetExceeded,
/// A deadline elapsed.
DeadlineExceeded,
/// The run was cancelled.
Cancelled,
/// A transport failed.
Transport,
/// A remote protocol was malformed or violated its contract.
Protocol,
/// An invoked component failed.
Invocation,
/// A namespaced extension error.
Extension(String),
}
/// A structured run error suitable for policy decisions.
#[derive(Clone, Debug, Deserialize, Error, PartialEq, Serialize)]
#[error("{kind:?}: {message}")]
pub struct RunError {
/// Normalized error category.
pub kind: RunErrorKind,
/// Safe human-readable explanation.
pub message: String,
/// Retry-safety classification.
pub retry_safety: RetrySafety,
/// Namespaced diagnostic metadata.
pub metadata: BTreeMap<String, Value>,
}