postproject_core/error.rs
1//! Domain-level errors that do not expose backend implementation details.
2
3/// Stable categories shared by core services and external adapters.
4#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
5#[non_exhaustive]
6pub enum ErrorKind {
7 /// A caller supplied invalid input.
8 InvalidArgument,
9 /// A requested domain object does not exist.
10 NotFound,
11 /// An object or relationship already exists.
12 AlreadyExists,
13 /// An operating-system I/O operation failed.
14 Io,
15 /// A persistence backend failed.
16 Storage,
17 /// A schema migration failed.
18 Migration,
19 /// Current state conflicts with the requested operation.
20 Conflict,
21 /// Media resolution produced multiple credible candidates.
22 AmbiguousResolution,
23 /// Media fingerprint calculation or validation failed.
24 Fingerprint,
25 /// The requested operation is not supported.
26 Unsupported,
27 /// An internal domain invariant was violated.
28 Internal,
29}
30
31/// An application-neutral error with a stable category and useful context.
32#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
33#[error("{message}")]
34pub struct Error {
35 kind: ErrorKind,
36 message: String,
37}
38
39impl Error {
40 /// Creates an error in `kind` with a human-readable message.
41 #[must_use]
42 pub fn new(kind: ErrorKind, message: impl Into<String>) -> Self {
43 Self {
44 kind,
45 message: message.into(),
46 }
47 }
48
49 /// Returns the stable error category.
50 #[must_use]
51 pub const fn kind(&self) -> ErrorKind {
52 self.kind
53 }
54
55 /// Returns the human-readable context.
56 #[must_use]
57 pub fn message(&self) -> &str {
58 &self.message
59 }
60}
61
62/// The result type returned by core domain operations.
63pub type Result<T> = std::result::Result<T, Error>;