pub enum StorageError {
Show 14 variants
NotFound {
capability: StorageCapability,
resource: &'static str,
key: String,
},
AlreadyExists {
capability: StorageCapability,
resource: &'static str,
key: String,
},
Conflict {
capability: StorageCapability,
operation: Cow<'static, str>,
message: String,
},
InvalidInput {
capability: StorageCapability,
operation: Cow<'static, str>,
message: String,
},
Unsupported {
capability: StorageCapability,
operation: Cow<'static, str>,
message: String,
},
Pool {
operation: Cow<'static, str>,
message: String,
},
Timeout {
operation: Cow<'static, str>,
},
Transaction {
operation: Cow<'static, str>,
message: String,
},
Serialization {
capability: StorageCapability,
message: String,
},
IndexMaintenance {
capability: StorageCapability,
message: String,
},
Driver {
capability: StorageCapability,
operation: Cow<'static, str>,
source: Box<dyn StdError + Send + Sync>,
},
WriteQueueFull {
timeout_ms: u64,
},
Internal(String),
WriterTaskNoRuntime,
}Expand description
Unified error type for all storage operations.
Variants§
NotFound
AlreadyExists
Conflict
InvalidInput
Unsupported
Pool
Timeout
Transaction
Serialization
IndexMaintenance
Driver
Fields
capability: StorageCapabilityWriteQueueFull
The bounded write-queue channel (ADR-067 Component A) did not free
capacity within the caller-supplied deadline. Returned only when a
caller wraps WriterTaskHandle::send’s channel.send().await in a
tokio::time::timeout — there is no immediate-error try_send path;
an un-timed-out send simply keeps applying backpressure.
Internal(String)
An internal write-queue plumbing failure not attributable to a specific storage capability: the writer task’s channel closed (the task panicked or was dropped) or its oneshot reply was dropped before sending a result.
WriterTaskNoRuntime
KHIVE_WRITE_QUEUE=1 is set but the calling thread has no Tokio
runtime context, so the writer task (which spawns via tokio::spawn)
cannot be started (ADR-067 Component A).
Returned instead of panicking: a caller that constructs a store from
a plain, non-async context with the flag on gets a clean, typed
failure at first write rather than a tokio::spawn-outside-runtime
panic. Flag-off callers never see this variant — writer_task_handle
only attempts to spawn when PoolConfig::write_queue_enabled is set.
Implementations§
Source§impl StorageError
impl StorageError
Sourcepub fn driver(
capability: StorageCapability,
operation: impl Into<Cow<'static, str>>,
source: impl StdError + Send + Sync + 'static,
) -> Self
pub fn driver( capability: StorageCapability, operation: impl Into<Cow<'static, str>>, source: impl StdError + Send + Sync + 'static, ) -> Self
Construct a Driver error wrapping a backend-specific error source.
Sourcepub fn capability(&self) -> Option<StorageCapability>
pub fn capability(&self) -> Option<StorageCapability>
Return the storage capability surface that produced this error, if any.
Sourcepub fn is_retryable(&self) -> bool
pub fn is_retryable(&self) -> bool
Whether this error is transient and the operation may succeed on retry.
Sourcepub fn is_fts5_syntax_error(&self) -> bool
pub fn is_fts5_syntax_error(&self) -> bool
Whether this error is an FTS5 query-parser rejection of the MATCH expression itself, as opposed to a connection/pool/driver-level failure of the text-search backend.
Callers that fail-open the FTS leg of a hybrid search (degrading to
vector-only results on a bad query string) MUST gate on this predicate
rather than on StorageError broadly. TextSearch::search returns the
same Driver variant for a malformed MATCH expression and for a
genuine backend outage (pool exhaustion, connection failure, reader
open failure) — treating every Err as degradable turns a real outage
into a silently-empty “successful” search (issue #389 round-2 High).
SQLite’s FTS5 query parser (sqlite3Fts5ParseError, fts5_expr.c)
prefixes every message it emits with the literal "fts5: " token —
e.g. fts5: syntax error near "@", fts5: parser stack overflow,
fts5: column queries are not supported (detail=none). This is a
stable SQLite-internal convention, not a substring picked to match one
observed message. It excludes non-parser FTS5 subsystem failures such
as fts5: error creating shadow table ... (schema/storage corruption)
by requiring the message to name one of the parser’s own failure
modes, not just the fts5: namespace prefix.
Only applies to Driver errors from the Text capability at the
fts_search operation — the exact seam Fts5TextSearch::search uses
(crates/khive-db/src/stores/text.rs). Pool, Timeout, Transaction,
and any other operation value (e.g. fts_count, open_fts_reader)
always propagate.
Sourcepub fn is_unique_constraint_violation(&self) -> bool
pub fn is_unique_constraint_violation(&self) -> bool
Whether this error is a UNIQUE constraint violation from a raw SQL
execute (e.g. an INSERT racing an existing row under the ledger’s
natural key). Callers that treat exact-key duplicates as a tolerated
no-op (ADR-081 §4 serve-ledger idempotency) MUST gate on this
predicate rather than swallowing every Driver error at execute —
that would also hide genuine write failures (disk full, corruption).
Only applies to Driver errors from the Sql capability at a single-
statement execute operation. khive-db’s sql_bridge labels this
operation differently depending on which SqlAccess seam produced the
writer — a bare transaction’s execute vs. a pooled writer()’s
pool_writer.execute vs. an explicit tx.execute — so all three are
accepted; batch/script variants are intentionally excluded since a
UNIQUE violation partway through a multi-statement batch is not the
same single-row-duplicate case this predicate exists to tolerate.
Trait Implementations§
Source§impl Debug for StorageError
impl Debug for StorageError
Source§impl Display for StorageError
impl Display for StorageError
Source§impl Error for StorageError
impl Error for StorageError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()