Skip to main content

systemprompt_database/
error.rs

1//! Typed error boundary for the database crate.
2//!
3//! `RepositoryError` is the canonical error returned from the crate's
4//! database-facing public signatures, including the dyn-safe
5//! `DatabaseProvider` / `DatabaseTransaction` trait surfaces. It composes
6//! `sqlx::Error` and `serde_json::Error` via `#[from]`; runtime invariant
7//! failures are routed through `RepositoryError::InvalidState`. The
8//! filesystem-only [`crate::squash_baseline`] module carries its own error
9//! type.
10
11use thiserror::Error;
12
13#[derive(Debug, Error)]
14pub enum RepositoryError {
15    #[error("Entity not found: {0}")]
16    NotFound(String),
17
18    #[error("Constraint violation: {0}")]
19    Constraint(String),
20
21    #[error("Database error: {0}")]
22    Database(#[from] sqlx::Error),
23
24    #[error("Serialization error: {0}")]
25    Serialization(#[from] serde_json::Error),
26
27    #[error("Invalid argument: {0}")]
28    InvalidArgument(String),
29
30    #[error("Invalid state: {0}")]
31    InvalidState(String),
32
33    #[error("Internal error: {0}")]
34    Internal(String),
35}
36
37pub type DatabaseResult<T> = Result<T, RepositoryError>;
38
39impl RepositoryError {
40    pub fn not_found<T: std::fmt::Display>(id: T) -> Self {
41        Self::NotFound(id.to_string())
42    }
43
44    pub fn constraint<T: Into<String>>(message: T) -> Self {
45        Self::Constraint(message.into())
46    }
47
48    pub fn invalid_argument<T: Into<String>>(message: T) -> Self {
49        Self::InvalidArgument(message.into())
50    }
51
52    pub fn internal<T: Into<String>>(message: T) -> Self {
53        Self::Internal(message.into())
54    }
55
56    pub fn invalid_state<T: Into<String>>(message: T) -> Self {
57        Self::InvalidState(message.into())
58    }
59
60    #[must_use]
61    pub const fn is_not_found(&self) -> bool {
62        matches!(self, Self::NotFound(_))
63    }
64
65    #[must_use]
66    pub const fn is_constraint(&self) -> bool {
67        matches!(self, Self::Constraint(_))
68    }
69}
70
71impl From<RepositoryError> for systemprompt_traits::RepositoryError {
72    fn from(err: RepositoryError) -> Self {
73        Self::Database(Box::new(err))
74    }
75}