1use crate::RuntimeCapability;
16use std::fmt::{Display, Formatter};
17
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub enum HawDBError {
20 Parse(String),
21 Semantic(String),
22 Storage(String),
23 StorageIntegrity(String),
24 Execution(String),
25 TransactionConflict {
26 read_epoch: u64,
27 committed_epoch: u64,
28 key: String,
29 },
30 AppendSequenceExhausted {
31 table: String,
32 watermark: i64,
33 requested: usize,
34 },
35 CapabilityUnavailable {
36 capability: RuntimeCapability,
37 },
38}
39
40impl Display for HawDBError {
41 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42 match self {
43 HawDBError::Parse(message) => write!(f, "parse error: {message}"),
44 HawDBError::Semantic(message) => write!(f, "semantic error: {message}"),
45 HawDBError::Storage(message) => write!(f, "storage error: {message}"),
46 HawDBError::StorageIntegrity(message) => {
47 write!(f, "storage integrity error: {message}")
48 }
49 HawDBError::Execution(message) => write!(f, "execution error: {message}"),
50 HawDBError::TransactionConflict {
51 read_epoch,
52 committed_epoch,
53 key,
54 } => write!(
55 f,
56 "transaction conflict on {key}: transaction read epoch {read_epoch}, conflicting commit epoch {committed_epoch}"
57 ),
58 HawDBError::AppendSequenceExhausted {
59 table,
60 watermark,
61 requested,
62 } => write!(
63 f,
64 "append commit sequence exhausted for table {table}: watermark={watermark}, requested={requested}"
65 ),
66 HawDBError::CapabilityUnavailable { capability } => {
67 write!(f, "capability unavailable: {}", capability.as_str())
68 }
69 }
70 }
71}
72
73impl std::error::Error for HawDBError {}
74
75impl HawDBError {
76 pub const fn is_retryable_transaction_conflict(&self) -> bool {
77 matches!(self, Self::TransactionConflict { .. })
78 }
79}
80
81pub type Result<T> = std::result::Result<T, HawDBError>;
82
83impl From<std::io::Error> for HawDBError {
84 fn from(error: std::io::Error) -> Self {
85 HawDBError::Storage(error.to_string())
86 }
87}