Files
wanderbooks/crates/ledger-core/src/error.rs
T

79 lines
2.7 KiB
Rust

//! Error type for the ledger engine.
use rust_decimal::Decimal;
use thiserror::Error;
/// Every way a ledger command can fail.
///
/// Variants are part of the engine's contract: agents adding features add
/// variants here rather than inventing ad-hoc error reporting.
#[derive(Debug, Error, PartialEq, Eq)]
pub enum LedgerError {
/// A journal entry must have at least two lines (one debit, one credit).
#[error("journal entry has fewer than two lines")]
TooFewLines,
/// Debits and credits must be exactly equal. No epsilon, ever.
#[error("journal entry does not balance: debits {debits} != credits {credits}")]
UnbalancedEntry {
/// Sum of debit lines.
debits: Decimal,
/// Sum of credit lines.
credits: Decimal,
},
/// Zero-amount lines are noise; they are rejected, not ignored.
#[error("journal line has a zero amount")]
ZeroAmountLine,
/// The referenced account does not exist in the chart of accounts.
#[error("unknown account id {0}")]
UnknownAccount(u64),
/// Placeholder (header) accounts organize the chart; they take no postings.
#[error("account '{0}' is a placeholder and cannot take postings")]
PlaceholderAccount(String),
/// All lines of an entry (and their accounts) must share one currency.
#[error("currency mismatch: expected {expected}, found {found}")]
CurrencyMismatch {
/// The currency that was expected.
expected: String,
/// The currency that was found.
found: String,
},
/// Currency codes are three ASCII letters (ISO 4217 alpha-3).
#[error("invalid currency code '{0}': must be three ASCII letters")]
InvalidCurrencyCode(String),
/// Posted entries are immutable. This is load-bearing: it is what makes
/// the ledger an audit trail instead of a spreadsheet.
#[error("entry {0} is already posted and immutable")]
EntryAlreadyPosted(u64),
/// Only posted entries can be reversed.
#[error("entry {0} is not posted yet")]
EntryNotPosted(u64),
/// The referenced journal entry does not exist.
#[error("entry {0} does not exist")]
UnknownEntry(u64),
/// Account codes must be unique within a chart of accounts.
#[error("account code '{0}' is already in use")]
DuplicateAccountCode(String),
/// Account codes must not be empty.
#[error("account code must not be empty")]
EmptyAccountCode,
/// The referenced parent account does not exist.
#[error("unknown parent account id {0}")]
UnknownParentAccount(u64),
/// Any attempt to mutate a posted entry: add lines, delete it, edit it.
#[error("cannot modify a posted entry; post a reversing entry instead")]
PostedEntryImmutable,
}