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