1use std::any::Any;
16
17use common_error::ext::{BoxedError, ErrorExt};
18use common_error::status_code::StatusCode;
19use common_macro::stack_trace_debug;
20use snafu::{Location, Snafu};
21
22#[derive(Snafu)]
23#[snafu(visibility(pub))]
24#[stack_trace_debug]
25pub enum Error {
26 #[snafu(display("Failed to install ring crypto provider: {}", msg))]
27 InitTlsProvider {
28 #[snafu(implicit)]
29 location: Location,
30 msg: String,
31 },
32 #[snafu(display("Failed to create default catalog and schema"))]
33 InitMetadata {
34 #[snafu(implicit)]
35 location: Location,
36 source: common_meta::error::Error,
37 },
38
39 #[snafu(display("Failed to init DDL manager"))]
40 InitDdlManager {
41 #[snafu(implicit)]
42 location: Location,
43 source: common_meta::error::Error,
44 },
45
46 #[snafu(display("Failed to init default timezone"))]
47 InitTimezone {
48 #[snafu(implicit)]
49 location: Location,
50 source: common_time::error::Error,
51 },
52
53 #[snafu(display("Failed to start procedure manager"))]
54 StartProcedureManager {
55 #[snafu(implicit)]
56 location: Location,
57 source: common_procedure::error::Error,
58 },
59
60 #[snafu(display("Failed to stop procedure manager"))]
61 StopProcedureManager {
62 #[snafu(implicit)]
63 location: Location,
64 source: common_procedure::error::Error,
65 },
66
67 #[snafu(display("Failed to start wal options allocator"))]
68 StartWalOptionsAllocator {
69 #[snafu(implicit)]
70 location: Location,
71 source: common_meta::error::Error,
72 },
73
74 #[snafu(display("Missing config, msg: {}", msg))]
75 MissingConfig {
76 msg: String,
77 #[snafu(implicit)]
78 location: Location,
79 },
80
81 #[snafu(display("Illegal config: {}", msg))]
82 IllegalConfig {
83 msg: String,
84 #[snafu(implicit)]
85 location: Location,
86 },
87
88 #[snafu(display("Failed to parse proxy options: {}", error))]
89 ParseProxyOpts {
90 #[snafu(source)]
91 error: reqwest::Error,
92 #[snafu(implicit)]
93 location: Location,
94 },
95
96 #[snafu(display("Failed to build reqwest client: {}", error))]
97 BuildClient {
98 #[snafu(implicit)]
99 location: Location,
100 #[snafu(source)]
101 error: reqwest::Error,
102 },
103
104 #[snafu(display("Failed to parse SQL: {}", sql))]
105 ParseSql {
106 sql: String,
107 #[snafu(implicit)]
108 location: Location,
109 source: query::error::Error,
110 },
111
112 #[snafu(display("Failed to plan statement"))]
113 PlanStatement {
114 #[snafu(implicit)]
115 location: Location,
116 source: query::error::Error,
117 },
118
119 #[snafu(display("Failed to load layered config"))]
120 LoadLayeredConfig {
121 #[snafu(source(from(common_config::error::Error, Box::new)))]
122 source: Box<common_config::error::Error>,
123 #[snafu(implicit)]
124 location: Location,
125 },
126
127 #[snafu(display("Failed to connect to Etcd at {etcd_addr}"))]
128 ConnectEtcd {
129 etcd_addr: String,
130 #[snafu(source)]
131 error: etcd_client::Error,
132 #[snafu(implicit)]
133 location: Location,
134 },
135
136 #[snafu(display("Failed to serde json"))]
137 SerdeJson {
138 #[snafu(source)]
139 error: serde_json::error::Error,
140 #[snafu(implicit)]
141 location: Location,
142 },
143
144 #[snafu(display("Failed to run http request: {reason}"))]
145 HttpQuerySql {
146 reason: String,
147 #[snafu(source)]
148 error: reqwest::Error,
149 #[snafu(implicit)]
150 location: Location,
151 },
152
153 #[snafu(display("Empty result from output"))]
154 EmptyResult {
155 #[snafu(implicit)]
156 location: Location,
157 },
158
159 #[snafu(display("Failed to manipulate file"))]
160 FileIo {
161 #[snafu(implicit)]
162 location: Location,
163 #[snafu(source)]
164 error: std::io::Error,
165 },
166
167 #[snafu(display("Failed to create directory {}", dir))]
168 CreateDir {
169 dir: String,
170 #[snafu(source)]
171 error: std::io::Error,
172 },
173
174 #[snafu(display("Failed to spawn thread"))]
175 SpawnThread {
176 #[snafu(source)]
177 error: std::io::Error,
178 },
179
180 #[snafu(display("Other error"))]
181 Other {
182 source: BoxedError,
183 #[snafu(implicit)]
184 location: Location,
185 },
186
187 #[snafu(display("Failed to build runtime"))]
188 BuildRuntime {
189 #[snafu(implicit)]
190 location: Location,
191 source: common_runtime::error::Error,
192 },
193
194 #[snafu(display("Failed to get cache from cache registry: {}", name))]
195 CacheRequired {
196 #[snafu(implicit)]
197 location: Location,
198 name: String,
199 },
200
201 #[snafu(display("Failed to build cache registry"))]
202 BuildCacheRegistry {
203 #[snafu(implicit)]
204 location: Location,
205 source: cache::error::Error,
206 },
207
208 #[snafu(display("Failed to initialize meta client"))]
209 MetaClientInit {
210 #[snafu(implicit)]
211 location: Location,
212 source: meta_client::error::Error,
213 },
214
215 #[snafu(display("Cannot find schema {schema} in catalog {catalog}"))]
216 SchemaNotFound {
217 catalog: String,
218 schema: String,
219 #[snafu(implicit)]
220 location: Location,
221 },
222
223 #[snafu(display("OpenDAL operator failed"))]
224 OpenDal {
225 #[snafu(implicit)]
226 location: Location,
227 #[snafu(source)]
228 error: opendal::Error,
229 },
230 #[snafu(display("S3 config need be set"))]
231 S3ConfigNotSet {
232 #[snafu(implicit)]
233 location: Location,
234 },
235 #[snafu(display("Output directory not set"))]
236 OutputDirNotSet {
237 #[snafu(implicit)]
238 location: Location,
239 },
240}
241
242pub type Result<T> = std::result::Result<T, Error>;
243
244impl ErrorExt for Error {
245 fn status_code(&self) -> StatusCode {
246 match self {
247 Error::InitMetadata { source, .. } | Error::InitDdlManager { source, .. } => {
248 source.status_code()
249 }
250
251 Error::MissingConfig { .. }
252 | Error::LoadLayeredConfig { .. }
253 | Error::IllegalConfig { .. }
254 | Error::InitTimezone { .. }
255 | Error::ConnectEtcd { .. }
256 | Error::CreateDir { .. }
257 | Error::EmptyResult { .. }
258 | Error::ParseProxyOpts { .. } => StatusCode::InvalidArguments,
259
260 Error::StartProcedureManager { source, .. }
261 | Error::StopProcedureManager { source, .. } => source.status_code(),
262 Error::StartWalOptionsAllocator { source, .. } => source.status_code(),
263 Error::HttpQuerySql { .. } => StatusCode::Internal,
264 Error::ParseSql { source, .. } | Error::PlanStatement { source, .. } => {
265 source.status_code()
266 }
267
268 Error::SerdeJson { .. }
269 | Error::FileIo { .. }
270 | Error::SpawnThread { .. }
271 | Error::InitTlsProvider { .. }
272 | Error::BuildClient { .. } => StatusCode::Unexpected,
273
274 Error::Other { source, .. } => source.status_code(),
275 Error::OpenDal { .. } => StatusCode::Internal,
276 Error::S3ConfigNotSet { .. } => StatusCode::InvalidArguments,
277 Error::OutputDirNotSet { .. } => StatusCode::InvalidArguments,
278
279 Error::BuildRuntime { source, .. } => source.status_code(),
280
281 Error::CacheRequired { .. } | Error::BuildCacheRegistry { .. } => StatusCode::Internal,
282 Error::MetaClientInit { source, .. } => source.status_code(),
283 Error::SchemaNotFound { .. } => StatusCode::DatabaseNotFound,
284 }
285 }
286
287 fn as_any(&self) -> &dyn Any {
288 self
289 }
290}