Skip to main content

StorageError

Enum StorageError 

Source
pub enum StorageError {
Show 23 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, }, BlobTooLarge { content_ref: ContentRef, max_bytes: u64, observed_at_least: u64, }, BlobSizeMismatch { content_ref: ContentRef, metadata_bytes: u64, actual_bytes: u64, }, BlobDigestMismatch { expected: ContentRef, actual: ContentRef, }, Pool { operation: Cow<'static, str>, message: String, }, Timeout { operation: Cow<'static, str>, }, AdmissionTimeout { operation: Cow<'static, str>, timeout_ms: u64, }, Transaction { operation: Cow<'static, str>, message: String, }, ReadTransactionAgeEvicted { operation: Cow<'static, str>, max_age_secs: u64, }, ReadTransactionAgeEvictionCleanupFailed { operation: Cow<'static, str>, max_age_secs: u64, 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, }, WriterTaskBusy { timeout_ms: u64, }, WriterTaskTerminated { request_state: WriterTaskRequestState, }, Internal(String), WriterTaskNoRuntime, CapacityFloor { capability: StorageCapability, volume: String, available_bytes: u64, floor_bytes: u64, },
}
Expand description

Unified error type for all storage operations.

Variants§

§

NotFound

Fields

§resource: &'static str
§

AlreadyExists

Fields

§resource: &'static str
§

Conflict

Fields

§operation: Cow<'static, str>
§message: String
§

InvalidInput

Fields

§operation: Cow<'static, str>
§message: String
§

Unsupported

Fields

§operation: Cow<'static, str>
§message: String
§

BlobTooLarge

The authoritative object is larger than the caller’s declared whole-buffer limit. observed_at_least is either opened-object metadata used for early refusal or the running byte count that first crossed the limit; metadata is not treated as the actual-byte bound.

Fields

§content_ref: ContentRef
§max_bytes: u64
§observed_at_least: u64
§

BlobSizeMismatch

The complete bounded body disagreed with metadata obtained from the same opened object / GET response.

Fields

§content_ref: ContentRef
§metadata_bytes: u64
§actual_bytes: u64
§

BlobDigestMismatch

The complete, size-consistent bounded body did not hash to the requested content-addressed reference.

Fields

§expected: ContentRef
§actual: ContentRef
§

Pool

Fields

§operation: Cow<'static, str>
§message: String
§

Timeout

Fields

§operation: Cow<'static, str>
§

AdmissionTimeout

A bounded wait for storage admission (a reader/writer handle slot or a pooled reader checkout) elapsed before anything was acquired. The operation never started, so retrying cannot duplicate a side effect — distinct from StorageError::Timeout, which makes no claim about whether work was in flight when the deadline expired.

Fields

§operation: Cow<'static, str>
§timeout_ms: u64

The configured admission deadline that elapsed, in milliseconds.

§

Transaction

Fields

§operation: Cow<'static, str>
§message: String
§

ReadTransactionAgeEvicted

A cached read-only handle’s admitted transaction pinned a WAL snapshot past the configured read_tx_max_age bound and was proactively rolled back so the next call can open a fresh snapshot (#1846). Distinct from the generic StorageError::Transaction variant — which also covers failed-cleanup and write-side ambiguity cases that are not uniformly safe to retry — so callers (and MCP dispatch) can recognize this specific, always-safe-to-retry condition by variant rather than by parsing rendered text.

Fields

§operation: Cow<'static, str>
§max_age_secs: u64
§

ReadTransactionAgeEvictionCleanupFailed

A cached read-only handle’s admitted transaction pinned a WAL snapshot past read_tx_max_age, and the proactive rollback used to end the eviction (#1846) did not restore autocommit, or the rollback itself failed. The connection is discarded either way rather than returned to the pool. The age check that triggered this still ran before any read on the connection, so — exactly like StorageError::ReadTransactionAgeEvicted — retrying the caller’s operation on a fresh connection is always safe; this variant exists only to keep that guarantee distinguishable from a clean eviction in the rendered message and to keep StorageError::Transaction (whose other cases are not uniformly safe to retry) out of this path.

Fields

§operation: Cow<'static, str>
§max_age_secs: u64
§message: String
§

Serialization

Fields

§message: String
§

IndexMaintenance

Fields

§message: String
§

Driver

Fields

§operation: Cow<'static, str>
§source: Box<dyn StdError + Send + Sync>
§

WriteQueueFull

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.

Fields

§timeout_ms: u64
§

WriterTaskBusy

SQLite refused the writer task’s BEGIN IMMEDIATE with SQLITE_BUSY/SQLITE_LOCKED until the configured busy timeout. The queue accepted the request, but its operation closure was never invoked, so retrying that one failed operation is safe.

Fields

§timeout_ms: u64
§

WriterTaskTerminated

A single-writer execution seam has terminated permanently. This is the historical writer-task variant and display name; the fail-closed pool-mutex fallback also uses it when transaction finalization becomes terminal. The state identifies what is known about this request at that boundary. Retrying on the same pool cannot recover the retired writer seam.

Fields

§

Internal(String)

An internal storage failure not attributable to a specific storage capability.

§

WriterTaskNoRuntime

KHIVE_WRITE_QUEUE=1 is set but the calling thread has no Tokio runtime context, so the writer task cannot be spawned (ADR-067 Component A). Returned instead of panicking. See crates/khive-storage/docs/api/error-taxonomy.md#writertasknoruntime.

§

CapacityFloor

A filesystem-backed capability (e.g. BlobStore) refused a write because volume’s available space, after accounting for the pending write, would drop below the configured free-space floor (khive#292).

Fields

§volume: String
§available_bytes: u64
§floor_bytes: u64

Implementations§

Source§

impl StorageError

Source

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.

Source

pub fn capability(&self) -> Option<StorageCapability>

Return the storage capability surface that produced this error, if any.

Source

pub fn is_retryable(&self) -> bool

Whether this error is transient and the operation may succeed on retry.

Source

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.

True only for Driver errors from the Text capability at the fts_search operation whose message names one of SQLite’s FTS5 parser failure modes (syntax error, stack overflow, unsupported column/phrase/NEAR query); all other errors return false.

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 — treating every Err as degradable turns a real backend outage into a silently-empty “successful” search (issue #389). See crates/khive-storage/docs/api/error-taxonomy.md#is_fts5_syntax_error.

Source

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 a natural key). True only for Driver errors from the Sql capability whose operation is one of execute, pool_writer.execute, or tx.execute, and whose message contains UNIQUE constraint failed. Batch/script operations are intentionally excluded.

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). See crates/khive-storage/docs/api/error-taxonomy.md#is_unique_constraint_violation.

Trait Implementations§

Source§

impl Debug for StorageError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for StorageError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for StorageError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.