Skip to main content

DbError

Enum DbError 

Source
pub enum DbError {
Show 27 variants Engine(Error), Migration { to: u32, reason: String, }, InvalidEdgeType(String), SingleOpenViolation { source_id: String, target_id: String, edge_type: String, }, NotFound(String), DimMismatch { got: usize, expected: usize, model: String, }, InvalidModelName(String), ModelNotRegistered { model: String, table: String, }, SubgraphTooLarge { n: usize, budget: usize, }, NegativeEdgeWeight { source_id: String, target_id: String, weight: f64, }, ReplayCorrupt { seq: i64, reason: String, }, SnapshotIncompatible { path: String, reason: String, }, PayloadVersion { got: u8, max: u8, }, ArchiveViolation { table: String, }, AttributeModeUnstated { as_of: String, }, DiagnosticConn { path: String, reason: String, }, ArchiveWindow { window: Duration, reason: String, }, InvalidTimestamp { value: String, reason: String, }, InvalidId { id: String, reason: String, }, OverlappingInterval { overlap: Box<Overlap>, }, CurrentDrift { n: usize, }, RebuildFailed { n: usize, }, RebuildInterrupted { reason: String, }, WriterUnavailable, WriterDroppedResponder, WriterStopped(String), RecordedAtRegression { got: String, had: String, },
}
Expand description

Central error type for the Macrame bitemporal ledger database.

Variants§

§

Engine(Error)

§

Migration

Fields

§to: u32
§reason: String
§

InvalidEdgeType(String)

§

SingleOpenViolation

Fields

§source_id: String
§target_id: String
§edge_type: String
§

NotFound(String)

§

DimMismatch

Fields

§got: usize
§expected: usize
§model: String
§

InvalidModelName(String)

A model name is spliced into DDL and queries as a table identifier, and identifiers cannot be bound as parameters. Validating the name is what makes that splice safe, so an invalid one is refused rather than escaped.

§

ModelNotRegistered

Fields

§model: String
§table: String
§

SubgraphTooLarge

Fields

§budget: usize
§

NegativeEdgeWeight

Dijkstra and A* settle a node permanently the first time they pop it, which is only sound when no later edge can reduce the distance — that is, when weights are non-negative. links.weight is a bare REAL NOT NULL with no CHECK, so the guarantee has to be established at load time. The alternative is a shortest-path result that is quietly just a path.

Fields

§source_id: String
§target_id: String
§weight: f64
§

ReplayCorrupt

Fields

§seq: i64
§reason: String
§

SnapshotIncompatible

A snapshot this build cannot read. Distinct from Self::ReplayCorrupt on purpose: corruption is a fault to report, an incompatible snapshot is the ordinary consequence of an upgrade, and the correct response is to discard the file and fold from the log instead (D-043).

Fields

§path: String
§reason: String
§

PayloadVersion

Fields

§got: u8
§max: u8
§

ArchiveViolation

Fields

§table: String
§

AttributeModeUnstated

A traversal asked about the past without saying which text it wanted (T3.2, D-085).

TraversalBuilder::as_of(ts) fixes the topology at ts. Node attributes are a second, independent question, and the default answer — AttributeMode::Current — is live text. That combination returns the past’s graph wearing the present’s titles, which is a legitimate thing to want and a terrible thing to get by accident.

It used to be a tracing::warn!, which is invisible in any application that has not configured a subscriber. This is the same statement as a value the caller cannot miss.

Fix by stating the mode: .attribute_mode(AttributeMode::AtTime) for the past’s text, or .attribute_mode(AttributeMode::Current) to affirm that live text is what was meant.

Fields

§as_of: String
§

DiagnosticConn

crate::Database::diagnostic_conn could not open the file read-only (T5.1, D-091).

Its own variant rather than NotFound, which renders “node {0} not found” — naming the wrong subject is the defect D-069 was written to correct, and a file is not a node.

The case worth the sentence is a missing file: SQLITE_OPEN_READ_ONLY drops SQLITE_OPEN_CREATE with it, so a path that does not exist is SQLITE_CANTOPEN rather than a fresh empty database. That is the right behaviour and an opaque error to receive.

Fields

§path: String
§reason: String
§

ArchiveWindow

crate::Database::archive_windowed was given a window it cannot use (T1.1, D-080).

Carries a reason rather than the numbers as fields because the two cases it covers are not the same shape — a zero-length window never advances at all, while a merely narrow one produces a session count that has to be quoted against the limit to mean anything. A caller reading this needs the sentence, not the struct.

It is an error rather than a silent clamp on purpose. Rounding a one-second window up to something workable would archive over boundaries the caller did not choose, and the caller cannot see that it happened.

Fields

§window: Duration
§reason: String
§

InvalidTimestamp

A timestamp that is not in canonical form (§4.1, D-029).

Distinct from Self::ReplayCorrupt, which is what this used to be (Wave 4.5). timestamp::normalize and timestamp::parse reported bad caller input as ReplayCorrupt { seq: 0 } — a claim that the ledger is damaged, carrying a sequence number that cannot exist because AUTOINCREMENT starts at 1. The same mistake as defect J: an error that names the wrong subject sends a caller to fix the wrong thing.

The value is reported rather than the provenance, because one function serves both directions — a caller passing 2026-01-01T00:00:00Z and a stored recorded_at that will not parse produce the same complaint about the same string. SystemClock::new is where the second case is interpreted, and it already logs and floors to the wall clock (D-027).

Fields

§value: String
§reason: String
§

InvalidId

An identifier the crate’s own encodings cannot represent (D-061).

Distinct from Self::NotFound, and the distinction is defect J: this id was refused, not looked up. validate_id used to return NotFound here, which tells a caller the thing is missing and invites them to create it — with the same id, which will be refused again.

Fields

§reason: String
§

OverlappingInterval

Two valid-time intervals for one relationship claim the same instant.

Distinct from Self::SingleOpenViolation, which is the storage layer’s guard and covers only the open sentinel. This is the general case, and it is refused at the API rather than by a trigger (D-060): raw SQL against the same file can still write an overlap, and §4.2 says so.

The consequence of allowing one is not an error later but a wrong answer: query_as_of_edges at an instant inside both returns the relationship twice, and every weighted algorithm downstream double-counts that edge.

Boxed, and it is the only variant that is (D-075). Seven Strings is 168 bytes, which made DbError — and therefore every Result in the crate, on the Ok path too — larger than clippy::result_large_err’s threshold the moment D-060 added it. The other variants are well under. Boxing the rarest one keeps the whole error small rather than trimming what a caller is told; matches!(err, OverlappingInterval { .. }) is unaffected, which is how every call site uses it.

Fields

§overlap: Box<Overlap>
§

CurrentDrift

Fields

§

RebuildFailed

Fields

§

RebuildInterrupted

A chunked shadow rebuild was abandoned rather than committed (T1.2, D-082).

Distinct from Self::RebuildFailed, and the distinction is the whole point: RebuildFailed means the repair ran and did not repair, which is a reason to distrust the ledger. This means the repair did not run — something invalidated the work in progress and it was discarded before it could be swapped in. links_current is untouched and whatever was true of it before is still true. The action is to retry.

Fields

§reason: String
§

WriterUnavailable

§

WriterDroppedResponder

§

WriterStopped(String)

The actor’s task did not join cleanly at crate::Database::close.

Distinct from Self::WriterUnavailable, which means the channel is gone while the handle is still in use. This is the shutdown path telling a caller that the write actor panicked — which close() used to swallow, so a database whose write path had died closed “successfully” (Wave 4.2).

§

RecordedAtRegression

Fields

Trait Implementations§

Source§

impl Debug for DbError

Source§

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

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

impl Display for DbError

Source§

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

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

impl Error for DbError

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
Source§

impl From<Error> for DbError

Source§

fn from(source: Error) -> Self

Converts to this type from the input type.

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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 = Infallible

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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more