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 watcher for file {}", path))]
79 FileWatch {
80 path: String,
81 #[snafu(source)]
82 error: notify::Error,
83 },
84
85 #[snafu(display("User is not authorized to perform this action"))]
86 PermissionDenied {
87 #[snafu(implicit)]
88 location: Location,
89 },
90}
91
92impl ErrorExt for Error {
93 fn status_code(&self) -> StatusCode {
94 match self {
95 Error::InvalidConfig { .. } => StatusCode::InvalidArguments,
96 Error::IllegalParam { .. } | Error::FromUtf8 { .. } => StatusCode::InvalidArguments,
97 Error::FileWatch { .. } => StatusCode::InvalidArguments,
98 Error::InternalState { .. } => StatusCode::Unexpected,
99 Error::Io { .. } => StatusCode::StorageUnavailable,
100 Error::AuthBackend { source, .. } => source.status_code(),
101
102 Error::UserNotFound { .. } => StatusCode::UserNotFound,
103 Error::UnsupportedPasswordType { .. } => StatusCode::UnsupportedPasswordType,
104 Error::UserPasswordMismatch { .. } => StatusCode::UserPasswordMismatch,
105 Error::AccessDenied { .. } => StatusCode::AccessDenied,
106 Error::PermissionDenied { .. } => StatusCode::PermissionDenied,
107 }
108 }
109
110 fn as_any(&self) -> &dyn std::any::Any {
111 self
112 }
113}
114
115pub type Result<T> = std::result::Result<T, Error>;