1use std::io;
4use std::time::Duration;
5
6use anyhow::Error as AnyError;
7use serde_json::Value;
8use thiserror::Error;
9
10#[derive(Debug, Error)]
11pub enum ExecError {
12 #[error("failed to resolve component `{component}`: {source}")]
13 Resolve {
14 component: String,
15 #[source]
16 source: ResolveError,
17 },
18 #[error("artifact verification failed for `{component}`: {source}")]
19 Verification {
20 component: String,
21 #[source]
22 source: VerificationError,
23 },
24 #[error("runtime error while executing `{component}`: {source}")]
25 Runner {
26 component: String,
27 #[source]
28 source: RunnerError,
29 },
30 #[error("action `{action}` not found on component `{component}`")]
31 NotFound { component: String, action: String },
32 #[error("tool `{component}` returned error `{code}` for action `{action}`")]
33 Tool {
34 component: String,
35 action: String,
36 code: String,
37 payload: Value,
38 },
39}
40
41impl ExecError {
42 pub fn resolve(component: impl Into<String>, source: ResolveError) -> Self {
43 Self::Resolve {
44 component: component.into(),
45 source,
46 }
47 }
48
49 pub fn verification(component: impl Into<String>, source: VerificationError) -> Self {
50 Self::Verification {
51 component: component.into(),
52 source,
53 }
54 }
55
56 pub fn runner(component: impl Into<String>, source: RunnerError) -> Self {
57 Self::Runner {
58 component: component.into(),
59 source,
60 }
61 }
62
63 pub fn not_found(component: impl Into<String>, action: impl Into<String>) -> Self {
64 Self::NotFound {
65 component: component.into(),
66 action: action.into(),
67 }
68 }
69
70 pub fn tool_error(
71 component: impl Into<String>,
72 action: impl Into<String>,
73 code: impl Into<String>,
74 payload: Value,
75 ) -> Self {
76 Self::Tool {
77 component: component.into(),
78 action: action.into(),
79 code: code.into(),
80 payload,
81 }
82 }
83}
84
85#[derive(Debug, Error)]
86pub enum ResolveError {
87 #[error("component was not found in the configured store(s)")]
88 NotFound,
89 #[error("I/O error while reading artifact")]
90 Io(#[from] io::Error),
91 #[error("tool store error: {0}")]
92 Store(AnyError),
93}
94
95#[derive(Debug, Error)]
96pub enum VerificationError {
97 #[error("digest mismatch: expected {expected}, got {actual}")]
98 DigestMismatch { expected: String, actual: String },
99 #[error("artifact is unsigned and policy does not allow it")]
100 UnsignedRejected,
101}
102
103#[derive(Debug, Error)]
104pub enum RunnerError {
105 #[error("wasm execution timed out after {elapsed:?}")]
106 Timeout { elapsed: Duration },
107 #[error("wasmtime error: {0}")]
108 Wasmtime(#[from] wasmtime::Error),
109 #[error("serde error: {0}")]
110 Serde(#[from] serde_json::Error),
111 #[error("action `{action}` not implemented by the tool")]
112 ActionNotFound { action: String },
113 #[error("runner is not implemented for this configuration")]
114 NotImplemented,
115}