relational_engine/
error.rs1use std::any::Any;
16
17use common_error::ext::{ErrorExt, RetryHint};
18use common_error::status_code::StatusCode;
19use common_macro::stack_trace_debug;
20use object_store::error::retry_hint_from_opendal_error;
21use serde_json::error::Error as JsonError;
22use snafu::{Location, Snafu};
23use store_api::storage::RegionId;
24
25#[derive(Snafu)]
26#[snafu(visibility(pub))]
27#[stack_trace_debug]
28pub enum Error {
29 #[snafu(display("Unsupported operation: {}", operation))]
30 Unsupported {
31 operation: String,
32 #[snafu(implicit)]
33 location: Location,
34 },
35
36 #[snafu(display("Unexpected engine: {}", engine))]
37 UnexpectedEngine {
38 engine: String,
39 #[snafu(implicit)]
40 location: Location,
41 },
42
43 #[snafu(display("Invalid region metadata"))]
44 InvalidMetadata {
45 source: store_api::metadata::MetadataError,
46 #[snafu(implicit)]
47 location: Location,
48 },
49
50 #[snafu(display("Region not found, region_id: {}", region_id))]
51 RegionNotFound {
52 region_id: RegionId,
53 #[snafu(implicit)]
54 location: Location,
55 },
56
57 #[snafu(display(
58 "Region already exists with a different definition, region_id: {}, reason: {}",
59 region_id,
60 reason
61 ))]
62 RegionExists {
63 region_id: RegionId,
64 reason: String,
65 #[snafu(implicit)]
66 location: Location,
67 },
68
69 #[snafu(display("Failed to check object from path: {}", path))]
70 CheckObject {
71 path: String,
72 #[snafu(implicit)]
73 location: Location,
74 #[snafu(source)]
75 error: object_store::Error,
76 },
77
78 #[snafu(display("Fail to encode object into json"))]
79 EncodeJson {
80 #[snafu(implicit)]
81 location: Location,
82 #[snafu(source)]
83 error: JsonError,
84 },
85
86 #[snafu(display("Fail to decode object from json"))]
87 DecodeJson {
88 #[snafu(implicit)]
89 location: Location,
90 #[snafu(source)]
91 error: JsonError,
92 },
93
94 #[snafu(display("Failed to store region manifest, region_id: {}", region_id))]
95 StoreRegionManifest {
96 #[snafu(source)]
97 error: object_store::Error,
98 region_id: RegionId,
99 #[snafu(implicit)]
100 location: Location,
101 },
102
103 #[snafu(display("Failed to load region manifest, region_id: {}", region_id))]
104 LoadRegionManifest {
105 #[snafu(source)]
106 error: object_store::Error,
107 region_id: RegionId,
108 #[snafu(implicit)]
109 location: Location,
110 },
111
112 #[snafu(display("Failed to delete region manifest, region_id: {},", region_id))]
113 DeleteRegionManifest {
114 #[snafu(source)]
115 error: object_store::Error,
116 region_id: RegionId,
117 #[snafu(implicit)]
118 location: Location,
119 },
120
121 #[snafu(display("Manifest already exists: {}", path))]
122 ManifestExists {
123 path: String,
124 #[snafu(implicit)]
125 location: Location,
126 },
127
128 #[snafu(display("Missing required field: {}", name))]
129 MissingRequiredField {
130 name: String,
131 #[snafu(implicit)]
132 location: Location,
133 },
134}
135
136pub type Result<T> = std::result::Result<T, Error>;
137
138impl ErrorExt for Error {
139 fn status_code(&self) -> StatusCode {
140 use Error::*;
141
142 match self {
143 Unsupported { .. } => StatusCode::Unsupported,
147
148 InvalidMetadata { .. } | MissingRequiredField { .. } => StatusCode::InvalidArguments,
149
150 RegionNotFound { .. } => StatusCode::RegionNotFound,
151
152 RegionExists { .. } => StatusCode::Unexpected,
153
154 CheckObject { .. }
155 | StoreRegionManifest { .. }
156 | LoadRegionManifest { .. }
157 | DeleteRegionManifest { .. } => StatusCode::StorageUnavailable,
158
159 EncodeJson { .. }
160 | DecodeJson { .. }
161 | ManifestExists { .. }
162 | UnexpectedEngine { .. } => StatusCode::Unexpected,
163 }
164 }
165
166 fn as_any(&self) -> &dyn Any {
167 self
168 }
169
170 fn retry_hint(&self) -> RetryHint {
171 use Error::*;
172
173 match self {
174 CheckObject { error, .. }
175 | StoreRegionManifest { error, .. }
176 | LoadRegionManifest { error, .. }
177 | DeleteRegionManifest { error, .. } => retry_hint_from_opendal_error(error),
178 _ => RetryHint::NonRetryable,
179 }
180 }
181}