cloudiful_server/core/
error.rs1use std::{fmt, path::PathBuf};
2
3#[derive(Clone, Debug, Eq, PartialEq)]
4pub enum ServerConfigError {
5 MissingListenAddr,
6 MissingCorsOrigins,
7 MissingCorsMethods,
8 InvalidCorsOrigin(String),
9 InvalidCorsMethod(String),
10 MissingTlsCertPath,
11 MissingTlsKeyPath,
12}
13
14impl fmt::Display for ServerConfigError {
15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16 match self {
17 Self::MissingListenAddr => write!(f, "listen_addr must not be empty"),
18 Self::MissingCorsOrigins => {
19 write!(
20 f,
21 "restricted CORS configuration requires at least one origin"
22 )
23 }
24 Self::MissingCorsMethods => {
25 write!(
26 f,
27 "restricted CORS configuration requires at least one method"
28 )
29 }
30 Self::InvalidCorsOrigin(origin) => {
31 write!(f, "restricted CORS origin is invalid: {origin}")
32 }
33 Self::InvalidCorsMethod(method) => {
34 write!(f, "restricted CORS method is invalid: {method}")
35 }
36 Self::MissingTlsCertPath => write!(f, "TLS configuration requires cert_path"),
37 Self::MissingTlsKeyPath => write!(f, "TLS configuration requires cert_key_path"),
38 }
39 }
40}
41
42impl std::error::Error for ServerConfigError {}
43
44#[derive(Debug)]
45pub enum TlsConfigLoadError {
46 OpenCertificate {
47 path: PathBuf,
48 source: std::io::Error,
49 },
50 ReadCertificates {
51 path: PathBuf,
52 source: std::io::Error,
53 },
54 OpenPrivateKey {
55 path: PathBuf,
56 source: std::io::Error,
57 },
58 ReadPrivateKey {
59 path: PathBuf,
60 source: std::io::Error,
61 },
62 MissingPrivateKey {
63 path: PathBuf,
64 },
65 InvalidConfig {
66 source: rustls::Error,
67 },
68}
69
70impl fmt::Display for TlsConfigLoadError {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 match self {
73 Self::OpenCertificate { path, source } => {
74 write!(
75 f,
76 "failed to open TLS certificate at {}: {source}",
77 path.display()
78 )
79 }
80 Self::ReadCertificates { path, source } => {
81 write!(
82 f,
83 "failed to read TLS certificates from {}: {source}",
84 path.display()
85 )
86 }
87 Self::OpenPrivateKey { path, source } => {
88 write!(
89 f,
90 "failed to open TLS private key at {}: {source}",
91 path.display()
92 )
93 }
94 Self::ReadPrivateKey { path, source } => {
95 write!(
96 f,
97 "failed to read TLS private key from {}: {source}",
98 path.display()
99 )
100 }
101 Self::MissingPrivateKey { path } => {
102 write!(f, "no TLS private key found in {}", path.display())
103 }
104 Self::InvalidConfig { source } => {
105 write!(f, "failed to build TLS server configuration: {source}")
106 }
107 }
108 }
109}
110
111impl std::error::Error for TlsConfigLoadError {
112 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
113 match self {
114 Self::OpenCertificate { source, .. }
115 | Self::ReadCertificates { source, .. }
116 | Self::OpenPrivateKey { source, .. }
117 | Self::ReadPrivateKey { source, .. } => Some(source),
118 Self::InvalidConfig { source } => Some(source),
119 Self::MissingPrivateKey { .. } => None,
120 }
121 }
122}
123
124#[derive(Debug)]
125pub enum ServerError {
126 Config(ServerConfigError),
127 Io(std::io::Error),
128 Tls(TlsConfigLoadError),
129}
130
131impl fmt::Display for ServerError {
132 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133 match self {
134 Self::Config(err) => err.fmt(f),
135 Self::Io(err) => err.fmt(f),
136 Self::Tls(err) => err.fmt(f),
137 }
138 }
139}
140
141impl std::error::Error for ServerError {
142 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
143 match self {
144 Self::Config(err) => Some(err),
145 Self::Io(err) => Some(err),
146 Self::Tls(err) => Some(err),
147 }
148 }
149}
150
151impl From<ServerConfigError> for ServerError {
152 fn from(value: ServerConfigError) -> Self {
153 Self::Config(value)
154 }
155}
156
157impl From<std::io::Error> for ServerError {
158 fn from(value: std::io::Error) -> Self {
159 Self::Io(value)
160 }
161}