1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//! [`KevyError`] — the single error type of the embeddable stack.
//!
//! Defined here because `kevy-store` sits at the bottom of every
//! consumer's dependency graph (kevy-embedded, kevy-client, kevy-persist,
//! kevy-rt and the server all already depend on it) and is the source of
//! the dominant structured error, [`StoreError`]. Hosting the unified
//! type here adds no dependency edge anywhere; the protocol crate
//! (`kevy-resp`) hosting it would require a protocol → store edge.
#[cfg(not(feature = "std"))]
use crate::nostd_prelude::*;
use crate::StoreError;
use core::fmt;
#[cfg(feature = "std")]
use std::io;
/// Unified result alias over [`KevyError`].
pub type KevyResult<T> = core::result::Result<T, KevyError>;
/// The error type of the embeddable stack: `kevy_embedded::Store` and
/// `kevy_client::Connection` surfaces return `Result<_, KevyError>`.
///
/// Structured errors stay structured — a wrong-type write arrives as
/// `KevyError::Store(StoreError::WrongType)`, not as stringly `io::Error`
/// text. `From<io::Error>` / `From<StoreError>` keep `?` ergonomic at
/// both the OS boundary and the store boundary.
#[derive(Debug)]
pub enum KevyError {
/// Structured store-semantic error (wrong type, non-integer,
/// overflow, out-of-memory, …).
Store(StoreError),
/// Operating-system / transport failure (file, socket, AOF).
#[cfg(feature = "std")]
Io(io::Error),
/// RESP-level failure on a client link: a server error reply
/// (`-ERR …` text preserved verbatim) or a malformed / unexpected
/// reply shape.
Protocol(String),
/// Write rejected: the target is a read-only replica.
ReadOnly,
/// Invalid argument to a typed API (bad flag combination, empty
/// prefix, malformed URL, …). Rejected before touching any state.
InvalidInput(String),
/// A named object (index, view, required key) doesn't exist.
NotFound(String),
/// The operation isn't available on this backend or build.
Unsupported(String),
/// A bounded blocking call ran out its timeout.
TimedOut,
/// The connection / in-process bus is gone (EOF).
Closed,
}
impl fmt::Display for KevyError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Store(e) => write!(f, "store error: {e:?}"),
#[cfg(feature = "std")]
Self::Io(e) => write!(f, "io error: {e}"),
Self::Protocol(msg) => write!(f, "protocol error: {msg}"),
Self::ReadOnly => {
write!(f, "READONLY You can't write against a read only replica")
}
Self::InvalidInput(msg) => write!(f, "invalid input: {msg}"),
Self::NotFound(what) => write!(f, "not found: {what}"),
Self::Unsupported(msg) => write!(f, "unsupported: {msg}"),
Self::TimedOut => write!(f, "timed out"),
Self::Closed => write!(f, "connection closed"),
}
}
}
impl core::error::Error for KevyError {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
match self {
#[cfg(feature = "std")]
Self::Io(e) => Some(e),
_ => None,
}
}
}
impl From<StoreError> for KevyError {
fn from(e: StoreError) -> Self {
Self::Store(e)
}
}
#[cfg(feature = "std")]
impl From<io::Error> for KevyError {
fn from(e: io::Error) -> Self {
Self::Io(e)
}
}