wsprism_core/
error.rs

1//! Shared error types across wsPrism crates.
2//!
3//! These errors form the stable surface area that the gateway can turn into
4//! client-facing responses (e.g., `sys.error` envelopes) while keeping internal
5//! implementation details encapsulated.
6//!
7//! Design goal: All fallible operations in core should return `WsPrismError`
8//! rather than panic. Combined with crate-level lint denies for panic/unwrap,
9//! this keeps production code resilient to malformed or hostile input.
10
11use thiserror::Error;
12
13/// Stable client-facing error codes.
14///
15/// These codes are used in outward-facing responses and logging to decouple
16/// client behavior from internal error variants.
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub enum ClientCode {
19    /// Invalid input / malformed message.
20    BadRequest,
21    /// Auth failed.
22    AuthFailed,
23    /// Rate limited.
24    RateLimited,
25    /// Payload too large.
26    PayloadTooLarge,
27    /// Not allowed by policy.
28    NotAllowed,
29    /// Resource exhausted
30    ResourceExhausted,
31    /// Unsupported protocol version.
32    UnsupportedVersion,
33    /// Internal server error.
34    Internal,
35}
36
37impl ClientCode {
38    /// String representation used in JSON responses.
39    pub fn as_str(self) -> &'static str {
40        match self {
41            ClientCode::BadRequest => "BAD_REQUEST",
42            ClientCode::AuthFailed => "AUTH_FAILED",
43            ClientCode::RateLimited => "RATE_LIMITED",
44            ClientCode::PayloadTooLarge => "PAYLOAD_TOO_LARGE",
45            ClientCode::NotAllowed => "NOT_ALLOWED",
46            ClientCode::ResourceExhausted => "RESOURCE_EXHAUSTED",
47            ClientCode::UnsupportedVersion => "UNSUPPORTED_VERSION",
48            ClientCode::Internal => "INTERNAL",
49        }
50    }
51}
52
53/// Convenient result alias for core operations.
54pub type Result<T> = std::result::Result<T, WsPrismError>;
55
56/// Unified error type used by core and gateway layers.
57#[derive(Debug, Error)]
58pub enum WsPrismError {
59    #[error("bad request: {0}")]
60    BadRequest(String),
61    #[error("auth failed")]
62    AuthFailed,
63    #[error("rate limited")]
64    RateLimited,
65    #[error("payload too large")]
66    PayloadTooLarge,
67    #[error("not allowed: {0}")]
68    NotAllowed(String),
69    #[error("resource exhausted: {0}")]
70    ResourceExhausted(String),
71    #[error("unsupported protocol version")]
72    UnsupportedVersion,
73    #[error("internal: {0}")]
74    Internal(String),
75}
76
77impl WsPrismError {
78    /// Map internal error to a stable client-facing code.
79    pub fn client_code(&self) -> ClientCode {
80        match self {
81            WsPrismError::BadRequest(_) => ClientCode::BadRequest,
82            WsPrismError::AuthFailed => ClientCode::AuthFailed,
83            WsPrismError::RateLimited => ClientCode::RateLimited,
84            WsPrismError::PayloadTooLarge => ClientCode::PayloadTooLarge,
85            WsPrismError::NotAllowed(_) => ClientCode::NotAllowed,
86            WsPrismError::ResourceExhausted(_) => ClientCode::ResourceExhausted,
87            WsPrismError::UnsupportedVersion => ClientCode::UnsupportedVersion,
88            WsPrismError::Internal(_) => ClientCode::Internal,
89        }
90    }
91}