Skip to main content

database_mcp_server/
error.rs

1//! Application error types for the MCP server.
2//!
3//! Defines [`AppError`] with variants for connection, security validation,
4//! and query execution failures. Configuration errors live in the
5//! `config` crate.
6
7/// Errors that can occur during MCP server operation.
8#[derive(Debug, thiserror::Error)]
9pub enum AppError {
10    /// Database connection failed.
11    #[error("Database connection error: {0}")]
12    Connection(String),
13
14    /// Query blocked by read-only mode.
15    #[error("Query blocked: only SELECT, SHOW, DESC, DESCRIBE, USE queries are allowed in read-only mode")]
16    ReadOnlyViolation,
17
18    /// `LOAD_FILE()` function blocked for security.
19    #[error("Operation forbidden: LOAD_FILE() is not allowed for security reasons")]
20    LoadFileBlocked,
21
22    /// INTO OUTFILE/DUMPFILE blocked for security.
23    #[error("Operation forbidden: SELECT INTO OUTFILE/DUMPFILE is not allowed for security reasons")]
24    IntoOutfileBlocked,
25
26    /// Multiple SQL statements blocked.
27    #[error("Query blocked: only single statements are allowed")]
28    MultiStatement,
29
30    /// Invalid database or table name identifier.
31    #[error("Invalid identifier '{0}': must not be empty, whitespace-only, or contain control characters")]
32    InvalidIdentifier(String),
33
34    /// Database query execution failed.
35    #[error("Database error: {0}")]
36    Query(String),
37
38    /// Table isn't found in database.
39    #[error("Table not found: {0}")]
40    TableNotFound(String),
41
42    /// JSON serialization failed.
43    #[error("Serialization error: {0}")]
44    Serialization(String),
45}
46
47impl From<serde_json::Error> for AppError {
48    fn from(e: serde_json::Error) -> Self {
49        Self::Serialization(e.to_string())
50    }
51}
52
53impl From<AppError> for rmcp::model::ErrorData {
54    fn from(e: AppError) -> Self {
55        Self::internal_error(e.to_string(), None)
56    }
57}