Skip to main content

cortex_core/
error.rs

1//! Pure-typing errors for `cortex-core`.
2//!
3//! These errors describe **shape** and **typing** failures: an ID string that
4//! cannot be parsed, a serialized record whose `schema_version` does not match
5//! what this build understands, a JSON value that fails structural validation.
6//!
7//! `cortex-core` performs **no I/O** (per BUILD_SPEC §8). Surface I/O failures
8//! at the crate boundary that owns them (`cortex-ledger`, `cortex-store`, …)
9//! by composing them with `CoreError` via the usual `From` wiring; do **not**
10//! add I/O variants here.
11
12use thiserror::Error;
13
14/// Errors raised by `cortex-core` parsing and validation.
15#[derive(Debug, Error, Clone, PartialEq, Eq)]
16pub enum CoreError {
17    /// A string failed to parse as a prefix-ULID identifier.
18    ///
19    /// Either the prefix did not match the expected variant (e.g. `trc_…`
20    /// passed where `evt_…` was required) or the ULID body was malformed.
21    #[error("id parse error: {0}")]
22    IdParse(String),
23
24    /// A persisted record was decoded with an unexpected `schema_version`.
25    ///
26    /// Producers MUST refuse to operate on records whose schema is newer than
27    /// they understand; consumers MAY upcast older records via documented
28    /// migrations. See [`crate::SCHEMA_VERSION`].
29    #[error("schema version mismatch: found {found}, expected {expected}")]
30    SchemaMismatch {
31        /// The version observed on the wire / in storage.
32        found: u16,
33        /// The version this build of `cortex-core` understands.
34        expected: u16,
35    },
36
37    /// A JSON value failed structural validation (missing field, wrong type,
38    /// constraint violation). The contained string is operator-facing detail.
39    #[error("json validation failed: {0}")]
40    JsonValidation(String),
41
42    /// Generic value-shape validation failure (non-JSON contexts: invariants,
43    /// pre-conditions on typed values).
44    ///
45    /// Prefer [`CoreError::JsonValidation`] for failures that originated in a
46    /// JSON decode / schema check.
47    #[error("validation failed: {0}")]
48    Validation(String),
49}
50
51/// Crate-wide `Result` alias.
52pub type CoreResult<T> = Result<T, CoreError>;
53
54/// Backwards-compat alias for the pre-Lane-1.A error name.
55///
56/// Other crates in the workspace still reference `cortex_core::CortexError`;
57/// keep this alias available until they are migrated to [`CoreError`] in a
58/// follow-up lane. **New code MUST use [`CoreError`] directly.** When all
59/// downstream call sites have moved over, drop this alias in a single PR
60/// alongside a `SCHEMA_VERSION` non-bump (this is an API rename, not a wire
61/// rename).
62pub use CoreError as CortexError;
63
64/// Backwards-compat alias for the pre-Lane-1.A `Result` alias.
65///
66/// See the migration note on [`CortexError`]. **New code MUST use
67/// [`CoreResult`] directly.**
68pub type CortexResult<T> = CoreResult<T>;
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73
74    #[test]
75    fn schema_mismatch_renders_clean_message() {
76        let e = CoreError::SchemaMismatch {
77            found: 2,
78            expected: 1,
79        };
80        assert_eq!(
81            e.to_string(),
82            "schema version mismatch: found 2, expected 1"
83        );
84    }
85
86    #[test]
87    fn id_parse_renders_clean_message() {
88        let e = CoreError::IdParse("bad".into());
89        assert_eq!(e.to_string(), "id parse error: bad");
90    }
91}