Skip to main content

dspk_stream/
error.rs

1//! Errors of a stream session.
2
3use std::fmt;
4
5/// What went wrong in a stream session.
6#[derive(Debug, thiserror::Error)]
7pub enum StreamError {
8    #[error("I/O: {0}")]
9    Io(#[from] std::io::Error),
10    #[error("TLS: {0}")]
11    Tls(String),
12    #[error("connect: {0}")]
13    Connect(#[from] quinn::ConnectError),
14    #[error("connection: {0}")]
15    Connection(#[from] quinn::ConnectionError),
16    #[error("read: {0}")]
17    Read(#[from] quinn::ReadExactError),
18    #[error("write: {0}")]
19    Write(#[from] quinn::WriteError),
20    #[error("message of {len} bytes exceeds the {max}-byte limit")]
21    TooLarge { len: usize, max: usize },
22    #[error("stream ended inside a message")]
23    Truncated,
24    #[error("decode: {0}")]
25    Decode(#[from] prost::DecodeError),
26    /// The peer sent something the protocol does not allow.
27    #[error("protocol: {0}")]
28    Protocol(String),
29    /// The server refused or failed a request, and said why.
30    #[error("server: {0}")]
31    Server(String),
32    #[error(transparent)]
33    Dsp(#[from] dspk_core::DspError),
34}
35
36impl StreamError {
37    pub(crate) fn protocol(message: impl fmt::Display) -> Self {
38        Self::Protocol(message.to_string())
39    }
40
41    /// What to tell a client about this error (the reason, without the kind's prefix).
42    pub(crate) fn reason(&self) -> String {
43        match self {
44            Self::Protocol(m) | Self::Server(m) | Self::Tls(m) => m.clone(),
45            other => other.to_string(),
46        }
47    }
48
49    /// The peer closed the connection (a client leaving), not a failure.
50    pub fn is_closed_by_peer(&self) -> bool {
51        use quinn::{ConnectionError, ReadError, ReadExactError};
52        matches!(
53            self,
54            Self::Connection(ConnectionError::ApplicationClosed(_) | ConnectionError::LocallyClosed)
55                | Self::Read(ReadExactError::ReadError(ReadError::ConnectionLost(ConnectionError::ApplicationClosed(_) | ConnectionError::LocallyClosed)))
56        )
57    }
58}
59
60pub type StreamResult<T> = Result<T, StreamError>;