Skip to main content

sz_orm_sqlx/
error.rs

1//! sqlx 错误到 sz-orm-core DbError 的映射
2
3use sz_orm_core::{DbError, PoolError};
4
5/// 将 sqlx::Error 转换为 DbError
6pub fn map_sqlx_error(e: sqlx::Error) -> DbError {
7    match e {
8        sqlx::Error::Database(db_err) => {
9            // 用 code() 和 message() 判断错误类型
10            let msg = db_err.message().to_string();
11            let code = db_err.code().map(|c| c.into_owned()).unwrap_or_default();
12            // PostgreSQL SQLSTATE codes
13            if code == "23505"
14                || msg.contains("Duplicate entry")
15                || msg.contains("unique constraint")
16            {
17                DbError::AlreadyExists(msg)
18            } else if code == "23503"
19                || code.starts_with("23")
20                || msg.contains("foreign key constraint")
21                || msg.contains("constraint")
22            {
23                DbError::ConstraintViolation(msg)
24            } else if code.starts_with("42") || msg.contains("syntax") {
25                DbError::InvalidInput(msg)
26            } else {
27                DbError::QueryError(msg)
28            }
29        }
30        sqlx::Error::PoolClosed => {
31            DbError::PoolError(PoolError::Internal("sqlx pool closed".to_string()))
32        }
33        sqlx::Error::PoolTimedOut => DbError::PoolError(PoolError::Timeout),
34        sqlx::Error::Io(io) => DbError::IoError(io.to_string()),
35        sqlx::Error::Tls(tls) => DbError::ConnectionError(tls.to_string()),
36        sqlx::Error::Protocol(p) => DbError::ConnectionError(p.to_string()),
37        sqlx::Error::RowNotFound => DbError::NotFound("row not found".to_string()),
38        other => DbError::Internal(other.to_string()),
39    }
40}