Skip to main content

acta_maker_sdk/ws/
error.rs

1use thiserror::Error;
2
3#[derive(Debug, Error)]
4#[non_exhaustive]
5pub enum WsClientError {
6    #[error("websocket error: {0}")]
7    WebSocket(#[from] tokio_tungstenite::tungstenite::Error),
8    #[error("json error: {0}")]
9    Json(#[from] serde_json::Error),
10    #[error("unreadable frame: {0}")]
11    UnreadableFrame(Box<UnreadableFrame>),
12    #[error("read timeout")]
13    Timeout,
14    #[error("websocket connect timed out")]
15    ConnectTimeout,
16    #[error("connection closed")]
17    ConnectionClosed,
18    #[error("protocol error: {0}")]
19    Protocol(String),
20    #[error(transparent)]
21    InvalidTransportConfig(#[from] WsTransportConfigError),
22}
23
24#[derive(Debug, Error, Clone, Copy, PartialEq, Eq)]
25#[non_exhaustive]
26pub enum WsTransportConfigError {
27    #[error("connect timeout must be non-zero")]
28    ZeroConnectTimeout,
29    #[error("websocket message and frame limits must be non-zero")]
30    ZeroMessageOrFrameLimit,
31    #[error("maximum write buffer size must exceed write buffer size")]
32    InvalidWriteBufferRange,
33}
34
35pub type WsResult<T> = Result<T, WsClientError>;
36
37/// A server frame this SDK version cannot decode. `frame_type` and `request_id` come from
38/// a lenient read of the raw JSON, when it is JSON at all.
39#[derive(Debug, Clone, PartialEq, Eq, Error)]
40#[error("{}: {error}", frame_type.as_deref().map_or("unknown type", |kind| kind))]
41pub struct UnreadableFrame {
42    pub frame_type: Option<String>,
43    pub request_id: Option<uuid::Uuid>,
44    pub error: String,
45}
46
47impl UnreadableFrame {
48    pub(crate) fn from_raw(raw: &[u8], error: &serde_json::Error) -> Self {
49        let value = serde_json::from_slice::<serde_json::Value>(raw).ok();
50        let frame_type = value
51            .as_ref()
52            .and_then(|value| value.get("type")?.as_str())
53            .map(str::to_owned);
54        let request_id = value
55            .as_ref()
56            .and_then(|value| value.get("data")?.get("request_id")?.as_str())
57            .and_then(|id| uuid::Uuid::parse_str(id).ok());
58        Self {
59            frame_type,
60            request_id,
61            error: error.to_string(),
62        }
63    }
64}