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("Authentication source failure"))]
42 AuthBackend {
43 #[snafu(implicit)]
44 location: Location,
45 #[snafu(source)]
46 source: BoxedError,
47 },
48
49 #[snafu(display("User not found, username: {}", username))]
50 UserNotFound { username: String },
51
52 #[snafu(display("Unsupported password type: {}", password_type))]
53 UnsupportedPasswordType { password_type: String },
54
55 #[snafu(display("Username and password does not match, username: {}", username))]
56 UserPasswordMismatch { username: String },
57
58 #[snafu(display(
59 "Access denied for user '{}' to database '{}-{}'",
60 username,
61 catalog,
62 schema
63 ))]
64 AccessDenied {
65 catalog: String,
66 schema: String,
67 username: String,
68 },
69
70 #[snafu(display("Failed to initialize a watcher for file {}", path))]
71 FileWatch {
72 path: String,
73 #[snafu(source)]
74 error: notify::Error,
75 },
76
77 #[snafu(display("User is not authorized to perform this action"))]
78 PermissionDenied {
79 #[snafu(implicit)]
80 location: Location,
81 },
82}
83
84impl ErrorExt for Error {
85 fn status_code(&self) -> StatusCode {
86 match self {
87 Error::InvalidConfig { .. } => StatusCode::InvalidArguments,
88 Error::IllegalParam { .. } => StatusCode::InvalidArguments,
89 Error::FileWatch { .. } => StatusCode::InvalidArguments,
90 Error::InternalState { .. } => StatusCode::Unexpected,
91 Error::Io { .. } => StatusCode::StorageUnavailable,
92 Error::AuthBackend { source, .. } => source.status_code(),
93
94 Error::UserNotFound { .. } => StatusCode::UserNotFound,
95 Error::UnsupportedPasswordType { .. } => StatusCode::UnsupportedPasswordType,
96 Error::UserPasswordMismatch { .. } => StatusCode::UserPasswordMismatch,
97 Error::AccessDenied { .. } => StatusCode::AccessDenied,
98 Error::PermissionDenied { .. } => StatusCode::PermissionDenied,
99 }
100 }
101
102 fn as_any(&self) -> &dyn std::any::Any {
103 self
104 }
105}
106
107pub type Result<T> = std::result::Result<T, Error>;