nodedb_graph/error.rs
1// SPDX-License-Identifier: Apache-2.0
2
3//! Typed error enum for the shared graph engine.
4//!
5//! Every fallible operation on `CsrIndex` (label interning, edge insert,
6//! edge delete) returns `Result<T, GraphError>`. Silent casts or
7//! `debug_assert!` at capacity boundaries reproduce the same class of
8//! bug they are trying to catch — loud, typed errors only.
9
10use nodedb_mem::MemError;
11use thiserror::Error;
12
13/// Hard upper bound on the number of distinct edge labels an individual
14/// `CsrIndex` can intern. `u32::MAX` is the type-theoretic ceiling;
15/// leaving one slot unused lets callers use `u32::MAX` as an "invalid"
16/// sentinel should they need it.
17pub const MAX_EDGE_LABELS: usize = (u32::MAX - 1) as usize;
18
19/// Hard upper bound on the number of nodes a single `CsrIndex` partition
20/// can hold. Each node occupies a `u32` dense index; at 4 GiB nodes the
21/// index space is exhausted. `u32::MAX` is reserved as an "invalid"
22/// sentinel, so the usable cap is `u32::MAX - 1`.
23///
24/// 4 billion nodes per collection is well beyond any realistic workload.
25/// Inserts beyond this limit are rejected with `GraphError::NodeOverflow`
26/// rather than silently wrapping the counter.
27pub const MAX_NODES_PER_CSR: usize = (u32::MAX - 1) as usize;
28
29/// Errors returned by graph-engine operations.
30#[derive(Debug, Error)]
31#[non_exhaustive]
32pub enum GraphError {
33 /// The CSR's edge-label id space is exhausted. Happens only when
34 /// more than `MAX_EDGE_LABELS` distinct labels have been interned
35 /// — in practice unreachable because the DSL ingress caps label
36 /// length and realistic workloads use orders of magnitude fewer
37 /// labels. Surfaced here so the failure mode is a typed error, not
38 /// a silent wrap (the bug this crate was shipping before).
39 #[error("CSR edge-label id space exhausted ({used}/{MAX_EDGE_LABELS} labels interned)")]
40 LabelOverflow { used: usize },
41
42 /// The CSR's node id space is exhausted. A single `CsrIndex` partition
43 /// supports at most `MAX_NODES_PER_CSR` (≈ 4 billion) distinct nodes.
44 /// Inserts beyond this limit are rejected rather than silently wrapping
45 /// the `u32` node index. Collections approaching this limit should be
46 /// sharded across multiple partitions.
47 #[error(
48 "CSR node id space exhausted ({used}/{MAX_NODES_PER_CSR} nodes); \
49 collection must be sharded to accept more nodes"
50 )]
51 NodeOverflow { used: usize },
52
53 /// The memory governor rejected a reservation for a graph operation.
54 ///
55 /// Callers should apply backpressure and retry after memory is released.
56 #[error("graph memory budget rejected: {0}")]
57 MemoryBudget(#[from] MemError),
58}