1#[derive(Debug, thiserror::Error)]
9#[non_exhaustive]
10pub enum BackendError {
11 #[error("authentication required")]
12 Unauthorized,
13 #[error("backend rejected the build [{code}]: {message}")]
14 Rejected { code: String, message: String },
15 #[error("not found: {0}")]
16 NotFound(String),
17 #[error("network error: {0}")]
18 Transport(String),
19 #[error("log stream error: {0}")]
20 LogStream(String),
21 #[error("local execution error: {0}")]
22 Local(String),
23 #[error("source archive is {observed_bytes} bytes (cap {cap_bytes})")]
28 SourceTooLarge {
29 observed_bytes: u64,
30 cap_bytes: u64,
31 largest_paths: Vec<(String, u64)>,
32 },
33 #[error(transparent)]
34 Other(#[from] Box<dyn std::error::Error + Send + Sync>),
35}
36
37pub type Result<T> = std::result::Result<T, BackendError>;
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 #[test]
44 fn unauthorized_is_matchable_and_displayed() {
45 let e = BackendError::Unauthorized;
46 assert!(matches!(e, BackendError::Unauthorized));
47 assert!(e.to_string().contains("authentication"));
48 }
49
50 #[test]
51 fn rejected_carries_code_and_message() {
52 let e = BackendError::Rejected {
53 code: "build_rejected".into(),
54 message: "bad IR".into(),
55 };
56 let s = e.to_string();
57 assert!(s.contains("build_rejected") && s.contains("bad IR"));
58 }
59}