Skip to main content

klieo_memory_pgvector/
error.rs

1//! Error mapping from `sqlx` errors to [`klieo_core::error::MemoryError`].
2
3use klieo_core::error::MemoryError;
4
5/// PostgreSQL SQLSTATE for `undefined_table` — raised when a query hits the
6/// facts table before the first `remember` has provisioned it.
7const UNDEFINED_TABLE: &str = "42P01";
8
9pub(crate) fn store_err(e: sqlx::Error) -> MemoryError {
10    MemoryError::Store(e.to_string())
11}
12
13/// Whether `e` is PostgreSQL's `undefined_table` (42P01). `recall` /
14/// `recall_filtered` map this to an empty result and `forget` to `Ok` — the
15/// table is created lazily on first `remember`, so a read that races ahead of
16/// any write sees "no facts", not a hard error (mirrors the Qdrant backend's
17/// missing-collection handling).
18pub(crate) fn is_undefined_table(e: &sqlx::Error) -> bool {
19    matches!(e, sqlx::Error::Database(db) if db.code().as_deref() == Some(UNDEFINED_TABLE))
20}
21
22#[cfg(test)]
23mod tests {
24    use super::*;
25
26    #[test]
27    fn store_err_routes_to_store_variant() {
28        let mem = store_err(sqlx::Error::PoolClosed);
29        assert!(matches!(mem, MemoryError::Store(_)));
30    }
31
32    #[test]
33    fn non_database_error_is_not_undefined_table() {
34        assert!(!is_undefined_table(&sqlx::Error::PoolClosed));
35    }
36}