systemprompt_traits/repository/
sqlx_classify.rs1use sqlx::error::ErrorKind;
7
8use super::{ConstraintKind, RepositoryError};
9
10const UNNAMED_CONSTRAINT: &str = "<unnamed>";
11
12impl From<sqlx::Error> for RepositoryError {
13 fn from(err: sqlx::Error) -> Self {
14 if matches!(err, sqlx::Error::RowNotFound) {
15 return Self::NotFound {
16 entity: "row",
17 key: None,
18 };
19 }
20 let classified = err.as_database_error().map(|db_error| {
21 let kind = match db_error.kind() {
22 ErrorKind::UniqueViolation => Some(ConstraintKind::Unique),
23 ErrorKind::ExclusionViolation => Some(ConstraintKind::Exclusion),
24 ErrorKind::ForeignKeyViolation => Some(ConstraintKind::ForeignKey),
25 ErrorKind::NotNullViolation => Some(ConstraintKind::NotNull),
26 ErrorKind::CheckViolation => Some(ConstraintKind::Check),
27 _ => None,
28 };
29 let constraint = db_error
30 .constraint()
31 .unwrap_or(UNNAMED_CONSTRAINT)
32 .to_owned();
33 let sqlstate = db_error.code().map(std::borrow::Cow::into_owned);
34 (kind, constraint, sqlstate)
35 });
36 match classified {
37 Some((Some(kind), constraint, _)) => Self::Constraint {
38 kind,
39 constraint,
40 source: Box::new(err),
41 },
42 Some((None, _, sqlstate)) => Self::Database {
43 sqlstate,
44 source: Box::new(err),
45 },
46 None => Self::Database {
47 sqlstate: None,
48 source: Box::new(err),
49 },
50 }
51 }
52}