1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, thiserror::Error)]
10pub enum ApiError {
11 #[error("the ceremony engine is unavailable: {reason}")]
12 Unavailable { reason: String },
13
14 #[error("no ceremony named `{ceremony_id}`")]
15 CeremonyNotFound { ceremony_id: String },
16
17 #[error("the ceremony engine refused: {reason}")]
18 Refused { reason: String },
19}
20
21impl ApiError {
22 #[must_use]
28 pub fn is_transient(&self) -> bool {
29 matches!(self, Self::Unavailable { .. })
30 }
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36
37 #[test]
38 fn only_unavailability_invites_a_retry() {
39 assert!(ApiError::Unavailable {
40 reason: "starting".to_owned()
41 }
42 .is_transient());
43 assert!(!ApiError::CeremonyNotFound {
44 ceremony_id: "c-1".to_owned()
45 }
46 .is_transient());
47 assert!(
48 !ApiError::Refused {
49 reason: "unbound definition".to_owned()
50 }
51 .is_transient(),
52 "retrying a refusal unchanged asks the same question and earns the \
53 same answer"
54 );
55 }
56}