Skip to main content

sentinel_proxy/acme/
error.rs

1//! ACME error types
2
3use std::io;
4use std::time::Duration;
5use thiserror::Error;
6
7use super::dns::DnsProviderError;
8
9/// Errors that can occur during ACME operations
10#[derive(Debug, Error)]
11pub enum AcmeError {
12    /// No ACME account has been initialized
13    #[error("ACME account not initialized - call init_account() first")]
14    NoAccount,
15
16    /// Failed to create or load ACME account
17    #[error("Failed to create ACME account: {0}")]
18    AccountCreation(String),
19
20    /// Failed to create certificate order
21    #[error("Failed to create certificate order: {0}")]
22    OrderCreation(String),
23
24    /// Challenge validation failed
25    #[error("Challenge validation failed for domain '{domain}': {message}")]
26    ChallengeValidation { domain: String, message: String },
27
28    /// Certificate finalization failed
29    #[error("Failed to finalize certificate: {0}")]
30    Finalization(String),
31
32    /// Storage operation failed
33    #[error("Storage error: {0}")]
34    Storage(#[from] StorageError),
35
36    /// ACME protocol error from instant-acme
37    #[error("ACME protocol error: {0}")]
38    Protocol(String),
39
40    /// Operation timed out
41    #[error("Operation timed out: {0}")]
42    Timeout(String),
43
44    /// No HTTP-01 challenge available for domain
45    #[error("No HTTP-01 challenge available for domain '{0}'")]
46    NoHttp01Challenge(String),
47
48    /// No DNS-01 challenge available for domain
49    #[error("No DNS-01 challenge available for domain '{0}'")]
50    NoDns01Challenge(String),
51
52    /// DNS provider not configured
53    #[error("DNS-01 challenge requires a DNS provider configuration")]
54    NoDnsProvider,
55
56    /// DNS provider operation failed
57    #[error("DNS provider error: {0}")]
58    DnsProvider(#[from] DnsProviderError),
59
60    /// DNS propagation timeout
61    #[error("DNS propagation timeout for record '{record}' after {elapsed:?}")]
62    PropagationTimeout { record: String, elapsed: Duration },
63
64    /// Wildcard domain requires DNS-01 challenge
65    #[error("Wildcard domain '{domain}' requires DNS-01 challenge type")]
66    WildcardRequiresDns01 { domain: String },
67
68    /// Certificate parsing error
69    #[error("Failed to parse certificate: {0}")]
70    CertificateParse(String),
71}
72
73/// Errors specific to certificate storage operations
74#[derive(Debug, Error)]
75pub enum StorageError {
76    /// IO error during file operations
77    #[error("IO error: {0}")]
78    Io(#[from] io::Error),
79
80    /// Failed to serialize/deserialize data
81    #[error("Serialization error: {0}")]
82    Serialization(String),
83
84    /// Storage directory not writable
85    #[error("Storage directory not writable: {path}")]
86    NotWritable { path: String },
87
88    /// Certificate not found
89    #[error("Certificate not found for domain: {domain}")]
90    CertificateNotFound { domain: String },
91
92    /// Invalid storage structure
93    #[error("Invalid storage structure: {0}")]
94    InvalidStructure(String),
95}
96
97impl From<serde_json::Error> for StorageError {
98    fn from(e: serde_json::Error) -> Self {
99        StorageError::Serialization(e.to_string())
100    }
101}
102
103impl From<instant_acme::Error> for AcmeError {
104    fn from(e: instant_acme::Error) -> Self {
105        AcmeError::Protocol(e.to_string())
106    }
107}