Skip to main content

appcore_ui/
error.rs

1// =============================================================================
2//        #######
3//     ###       ###     F: error.rs
4//    ##   ## ##   ##    P: AppCore-Runtime
5//         ## ##
6//                       C: 2026/10/13 00:00:00 by dnettoRaw
7//    ##   ## ##   ##    U: 2026/10/13 00:00:00 by dnettoRaw
8//      ###########      S: 0.1.0-beta.1
9// =============================================================================
10
11//! Controlled UI failures without free-form provider details or opaque payloads.
12use serde::{Deserialize, Serialize};
13use std::fmt;
14/// Result at a UI infrastructure boundary.
15pub type UiResult<T> = Result<T, UiError>;
16/// Stable wire error codes; errors never contain credentials or application data.
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
18#[serde(rename_all = "snake_case")]
19#[non_exhaustive]
20pub enum UiError {
21    /// An unsupported protocol input was presented.
22    UnsupportedVersion,
23    /// The JSON frame is malformed.
24    InvalidFrame,
25    /// An identifier or operation violates the contract.
26    InvalidRequest,
27    /// Encoded or decoded data exceeds the selected budget.
28    PayloadTooLarge,
29    /// A command omitted its validated idempotency key.
30    IdempotencyRequired,
31    /// An equivalent command is still executing or requires effect reconciliation.
32    IdempotencyPending,
33    /// A key was reused for a semantically different operation.
34    IdempotencyConflict,
35    /// A valid authenticated principal is required.
36    AuthenticationRequired,
37    /// The owning authorization policy denies this operation.
38    Forbidden,
39    /// Admission or subscription capacity is exhausted.
40    Busy,
41    /// The selected transport/backend is unavailable.
42    Unavailable,
43    /// Cooperative cancellation was requested.
44    Cancelled,
45    /// The monotonic execution budget elapsed.
46    DeadlineExceeded,
47    /// The surface no longer admits operations.
48    Closed,
49    /// A subscription no longer exists in this surface generation.
50    SubscriptionNotFound,
51    /// A sequence cannot safely advance without identity reuse.
52    SequenceExhausted,
53    /// An owning backend failed; its raw detail remains outside the wire response.
54    BackendFailure,
55}
56impl fmt::Display for UiError {
57    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58        if *self == Self::UnsupportedVersion {
59            return f.write_str("NO MORE SUPPORTED PLEASE UPDATE");
60        }
61        f.write_str(match self {
62            Self::UnsupportedVersion => "NO MORE SUPPORTED PLEASE UPDATE",
63            Self::InvalidFrame => "invalid UI frame",
64            Self::InvalidRequest => "invalid UI request",
65            Self::PayloadTooLarge => "UI payload limit exceeded",
66            Self::IdempotencyRequired => "UI command requires idempotency",
67            Self::IdempotencyPending => "UI command completion pending",
68            Self::IdempotencyConflict => "UI command idempotency conflict",
69            Self::AuthenticationRequired => "UI authentication required",
70            Self::Forbidden => "UI operation forbidden",
71            Self::Busy => "UI capacity exhausted",
72            Self::Unavailable => "UI transport unavailable",
73            Self::Cancelled => "UI operation cancelled",
74            Self::DeadlineExceeded => "UI deadline exceeded",
75            Self::Closed => "UI surface closed",
76            Self::SubscriptionNotFound => "UI subscription not found",
77            Self::SequenceExhausted => "UI sequence exhausted",
78            Self::BackendFailure => "UI backend failure",
79        })
80    }
81}
82impl std::error::Error for UiError {}