1use common_error::ext::{BoxedError, ErrorExt};
16use common_error::status_code::StatusCode;
17use common_macro::stack_trace_debug;
18use snafu::{Location, Snafu};
19
20#[derive(Snafu)]
21#[snafu(visibility(pub))]
22#[stack_trace_debug]
23pub enum Error {
24 #[snafu(display("Invalid config value: {}, {}", value, msg))]
25 InvalidConfig { value: String, msg: String },
26
27 #[snafu(display("Illegal param: {}", msg))]
28 IllegalParam { msg: String },
29
30 #[snafu(display("Internal state error: {}", msg))]
31 InternalState { msg: String },
32
33 #[snafu(display("IO error"))]
34 Io {
35 #[snafu(source)]
36 error: std::io::Error,
37 #[snafu(implicit)]
38 location: Location,
39 },
40
41 #[snafu(display("Failed to convert to utf8"))]
42 FromUtf8 {
43 #[snafu(source)]
44 error: std::string::FromUtf8Error,
45 #[snafu(implicit)]
46 location: Location,
47 },
48
49 #[snafu(display("Authentication source failure"))]
50 AuthBackend {
51 #[snafu(implicit)]
52 location: Location,
53 #[snafu(source)]
54 source: BoxedError,
55 },
56
57 #[snafu(display("User not found, username: {}", username))]
58 UserNotFound { username: String },
59
60 #[snafu(display("Unsupported password type: {}", password_type))]
61 UnsupportedPasswordType { password_type: String },
62
63 #[snafu(display("Username and password does not match, username: {}", username))]
64 UserPasswordMismatch { username: String },
65
66 #[snafu(display(
67 "Access denied for user '{}' to database '{}-{}'",
68 username,
69 catalog,
70 schema
71 ))]
72 AccessDenied {
73 catalog: String,
74 schema: String,
75 username: String,
76 },
77
78 #[snafu(display("Failed to initialize a file watcher"))]
79 FileWatch {
80 #[snafu(source)]
81 source: common_config::error::Error,
82 #[snafu(implicit)]
83 location: Location,
84 },
85
86 #[snafu(display("User is not authorized to perform this action"))]
87 PermissionDenied {
88 #[snafu(implicit)]
89 location: Location,
90 },
91}
92
93impl ErrorExt for Error {
94 fn status_code(&self) -> StatusCode {
95 match self {
96 Error::InvalidConfig { .. } => StatusCode::InvalidArguments,
97 Error::IllegalParam { .. } | Error::FromUtf8 { .. } => StatusCode::InvalidArguments,
98 Error::FileWatch { .. } => StatusCode::InvalidArguments,
99 Error::InternalState { .. } => StatusCode::Unexpected,
100 Error::Io { .. } => StatusCode::StorageUnavailable,
101 Error::AuthBackend { source, .. } => source.status_code(),
102
103 Error::UserNotFound { .. } => StatusCode::UserNotFound,
104 Error::UnsupportedPasswordType { .. } => StatusCode::UnsupportedPasswordType,
105 Error::UserPasswordMismatch { .. } => StatusCode::UserPasswordMismatch,
106 Error::AccessDenied { .. } => StatusCode::AccessDenied,
107 Error::PermissionDenied { .. } => StatusCode::PermissionDenied,
108 }
109 }
110
111 fn as_any(&self) -> &dyn std::any::Any {
112 self
113 }
114}
115
116pub type Result<T> = std::result::Result<T, Error>;