reconnecting_websocket/
error.rs

1use std::fmt::Debug;
2
3use gloo::{
4    net::websocket::{Message, WebSocketError},
5    utils::errors::JsError,
6};
7
8use crate::{error, SocketInput, SocketOutput};
9
10/// Errors returned by [`crate::Socket`] and [`crate::SocketBuilder`]
11#[derive(Debug, thiserror::Error)]
12pub enum Error<I, O>
13where
14    I: SocketInput,
15    O: SocketOutput,
16    Message: TryFrom<I>,
17    <Message as TryFrom<I>>::Error: Debug,
18    <O as TryFrom<Message>>::Error: Debug,
19{
20    /// Errors from the underlying [`gloo::net::websocket::futures::WebSocket`]
21    ///
22    /// These are unlikely to be fatal, they mostly express various ways the websocket has
23    /// disconnected or encountered an error that requires reconnecting
24    #[error("WebSocketError: {0}")]
25    WebSocketError(WebSocketError),
26
27    /// Javascript errors returned by either [`crate::get_proto_and_host`] or the underlying
28    /// [`gloo::net::websocket::futures::WebSocket`]
29    ///
30    /// These errors are often fatal errors like the URL provided is invalid, the port is
31    /// firewalled or other miscellaneous errors from the browser. Look at
32    /// [`gloo::net::websocket::futures::WebSocket::open`] to work out what the cases are and
33    /// how to handle them
34    #[error("JsError: {0}")]
35    JsError(#[from] JsError),
36
37    /// Invalid configuration provided to [`crate::SocketBuilder`]
38    ///
39    /// These errors are only returned from the bulder and are all fatal
40    #[error("InvalidConfig: {0}")]
41    InvalidConfig(String),
42
43    /// Input errors returned by the consumers implementation of <[`crate::Message`] as
44    /// [`TryFrom<I>`]>
45    ///
46    /// If these errors are fatal is dependent on consumers implementation of [`TryFrom<I>`]
47    #[error("Input TryFrom(Message) Err: {0:?}")]
48    InputError(<Message as TryFrom<I>>::Error),
49
50    /// Output errors returned by the consumers implementation of <O as [`TryFrom<Message>`]>
51    ///
52    /// If these errors are fatal is dependent on consumers implementation of [`TryFrom<Message>`]
53    #[error("Output TryFrom<Message> Err: {0:?}")]
54    OutputError(<O as TryFrom<Message>>::Error),
55}
56
57impl<I, O> From<WebSocketError> for Error<I, O>
58where
59    I: SocketInput,
60    O: SocketOutput,
61    Message: TryFrom<I>,
62    <Message as TryFrom<I>>::Error: Debug,
63    <O as TryFrom<Message>>::Error: Debug,
64{
65    fn from(err: WebSocketError) -> Self {
66        error!("WebSocketError: {err:?}");
67        Self::WebSocketError(err)
68    }
69}
70
71impl<I, O> Error<I, O>
72where
73    I: SocketInput,
74    O: SocketOutput,
75    Message: TryFrom<I>,
76    <Message as TryFrom<I>>::Error: Debug,
77    <O as TryFrom<Message>>::Error: Debug,
78{
79    pub(crate) fn from_input(err: <I as TryInto<Message>>::Error) -> Self {
80        error!("Input TryInto<Message> Error: {err:?}");
81        Self::InputError(err)
82    }
83
84    pub(crate) fn from_output(err: <O as TryFrom<Message>>::Error) -> Self {
85        error!("Output TryFrom<Message> Error: {err:?}");
86        Self::OutputError(err)
87    }
88}