1#[derive(Debug, thiserror::Error)]
5pub enum SqlError {
6 #[error("Query blocked: only SELECT, SHOW, DESC, DESCRIBE, USE queries are allowed in read-only mode")]
8 ReadOnlyViolation,
9
10 #[error("Operation forbidden: LOAD_FILE() is not allowed for security reasons")]
12 LoadFileBlocked,
13
14 #[error("Operation forbidden: {0}() is not allowed for security reasons")]
16 DangerousFunctionBlocked(String),
17
18 #[error("Operation forbidden: SELECT INTO OUTFILE/DUMPFILE is not allowed for security reasons")]
20 IntoOutfileBlocked,
21
22 #[error("Query blocked: only single statements are allowed")]
24 MultiStatement,
25
26 #[error("Invalid identifier '{0}': must not be empty, whitespace-only, or contain control characters")]
28 InvalidIdentifier(String),
29
30 #[error("Query timed out after {elapsed_secs:.1}s: {sql}")]
32 QueryTimeout {
33 elapsed_secs: f64,
35 sql: String,
37 },
38
39 #[error("Database error: {0}")]
41 Query(String),
42
43 #[error("Table not found: {0}")]
45 TableNotFound(String),
46}
47
48impl From<SqlError> for rmcp::model::ErrorData {
49 fn from(e: SqlError) -> Self {
50 Self::internal_error(e.to_string(), None)
51 }
52}