1use std::any::Any;
16
17use common_error::ext::{BoxedError, ErrorExt, RetryHint};
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 open metadata kvbackend"))]
27 OpenMetadataKvBackend {
28 #[snafu(implicit)]
29 location: Location,
30 source: BoxedError,
31 },
32
33 #[snafu(display("Operation to region server failed"))]
34 InvokeRegionServer {
35 #[snafu(implicit)]
36 location: Location,
37 source: servers::error::Error,
38 },
39
40 #[snafu(display("External error"))]
41 External {
42 source: BoxedError,
43 #[snafu(implicit)]
44 location: Location,
45 },
46
47 #[snafu(display("Failed to parse url: {}", url))]
48 ParseUrl {
49 url: String,
50 #[snafu(implicit)]
51 location: Location,
52 #[snafu(source)]
53 error: url::ParseError,
54 },
55
56 #[snafu(display("Invalid url scheme: {}", scheme))]
57 InvalidUrlScheme { scheme: String },
58
59 #[snafu(display("Invalid region request, reason: {}", reason))]
60 InvalidRegionRequest { reason: String },
61
62 #[snafu(display("Repartition procedure is not supported in standalone mode"))]
63 NoSupportRepartitionProcedure {
64 #[snafu(implicit)]
65 location: Location,
66 },
67}
68
69pub type Result<T> = std::result::Result<T, Error>;
70
71impl ErrorExt for Error {
72 fn status_code(&self) -> StatusCode {
73 match self {
74 Error::OpenMetadataKvBackend { source, .. } => source.status_code(),
75 Error::InvokeRegionServer { source, .. } => source.status_code(),
76 Error::External { source, .. } => source.status_code(),
77 Error::ParseUrl { .. } => StatusCode::InvalidArguments,
78 Error::InvalidUrlScheme { .. } => StatusCode::InvalidArguments,
79 Error::InvalidRegionRequest { .. } => StatusCode::IllegalState,
80 Error::NoSupportRepartitionProcedure { .. } => StatusCode::Unsupported,
81 }
82 }
83
84 fn as_any(&self) -> &dyn Any {
85 self
86 }
87
88 fn retry_hint(&self) -> RetryHint {
89 match self {
90 Error::InvokeRegionServer { source, .. } => source.retry_hint(),
91 _ => RetryHint::NonRetryable,
92 }
93 }
94}