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 {}