1use thiserror::Error;
4
5#[derive(Error, Debug)]
6pub enum DiscoverError {
7 #[error("invalid config: {0}")]
8 InvalidConfig(String),
9
10 #[error("failed to build task spec: {0}")]
11 SpecBuild(String),
12
13 #[cfg(feature = "grpc")]
14 #[error("failed to connect to control plane: {0}")]
15 GrpcTransport(#[from] tonic::transport::Error),
16
17 #[cfg(feature = "grpc")]
18 #[error("grpc call failed: {0}")]
19 GrpcStatus(#[source] Box<tonic::Status>),
20
21 #[cfg(feature = "http")]
22 #[error("http request failed: {0}")]
23 HttpRequest(#[from] reqwest::Error),
24
25 #[cfg(feature = "http")]
26 #[error("http status {code}: {body}")]
27 HttpStatus { code: u16, body: String },
28
29 #[cfg(feature = "http")]
30 #[error("invalid response: {0}")]
31 InvalidResponse(String),
32
33 #[error("control plane rejected sync: {reason}")]
34 Rejected {
35 reason: String,
36 retry_after_s: Option<i32>,
37 },
38
39 #[error("authentication failed: {reason}")]
40 AuthFailed { reason: String },
41}
42
43impl DiscoverError {
44 pub fn is_terminal(&self) -> bool {
47 matches!(
48 self,
49 DiscoverError::AuthFailed { .. } | DiscoverError::InvalidConfig(_)
50 )
51 }
52}
53
54#[cfg(feature = "grpc")]
55impl From<tonic::Status> for DiscoverError {
56 fn from(status: tonic::Status) -> Self {
57 DiscoverError::GrpcStatus(Box::new(status))
58 }
59}