scuffle_rtmp/session/
errors.rs

1use std::fmt;
2
3use crate::channels::UniqueID;
4use crate::chunk::ChunkDecodeError;
5use crate::handshake::HandshakeError;
6use crate::macros::from_error;
7use crate::messages::MessageError;
8use crate::netconnection::NetConnectionError;
9use crate::netstream::NetStreamError;
10use crate::protocol_control_messages::ProtocolControlMessageError;
11use crate::user_control_messages::EventMessagesError;
12
13#[derive(Debug)]
14pub enum SessionError {
15    Handshake(HandshakeError),
16    Message(MessageError),
17    ChunkDecode(ChunkDecodeError),
18    ProtocolControlMessage(ProtocolControlMessageError),
19    NetStream(NetStreamError),
20    NetConnection(NetConnectionError),
21    EventMessages(EventMessagesError),
22    UnknownStreamID(u32),
23    PublisherDisconnected(UniqueID),
24    Io(std::io::Error),
25    Timeout(tokio::time::error::Elapsed),
26    NoAppName,
27    NoStreamName,
28    PublishRequestDenied,
29    ConnectRequestDenied,
30    PlayNotSupported,
31    PublisherDropped,
32    InvalidChunkSize(usize),
33}
34
35impl SessionError {
36    pub fn is_client_closed(&self) -> bool {
37        match self {
38            Self::Io(err) => matches!(
39                err.kind(),
40                std::io::ErrorKind::ConnectionAborted
41                    | std::io::ErrorKind::ConnectionReset
42                    | std::io::ErrorKind::UnexpectedEof
43            ),
44            Self::Timeout(_) => true,
45            _ => false,
46        }
47    }
48}
49
50from_error!(SessionError, Self::Handshake, HandshakeError);
51from_error!(SessionError, Self::Message, MessageError);
52from_error!(SessionError, Self::ChunkDecode, ChunkDecodeError);
53from_error!(SessionError, Self::ProtocolControlMessage, ProtocolControlMessageError);
54from_error!(SessionError, Self::NetStream, NetStreamError);
55from_error!(SessionError, Self::NetConnection, NetConnectionError);
56from_error!(SessionError, Self::EventMessages, EventMessagesError);
57from_error!(SessionError, Self::Io, std::io::Error);
58from_error!(SessionError, Self::Timeout, tokio::time::error::Elapsed);
59
60impl fmt::Display for SessionError {
61    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
62        match self {
63            Self::Io(error) => write!(f, "io error: {}", error),
64            Self::Handshake(error) => write!(f, "handshake error: {}", error),
65            Self::Message(error) => write!(f, "message error: {}", error),
66            Self::ChunkDecode(error) => write!(f, "chunk decode error: {}", error),
67            Self::ProtocolControlMessage(error) => {
68                write!(f, "protocol control message error: {}", error)
69            }
70            Self::NetStream(error) => write!(f, "netstream error: {}", error),
71            Self::NetConnection(error) => write!(f, "netconnection error: {}", error),
72            Self::EventMessages(error) => write!(f, "event messages error: {}", error),
73            Self::UnknownStreamID(id) => write!(f, "unknown stream id: {}", id),
74            Self::PublisherDisconnected(name) => write!(f, "publisher disconnected: {}", name),
75            Self::NoAppName => write!(f, "no app name"),
76            Self::NoStreamName => write!(f, "no stream name"),
77            Self::PublishRequestDenied => write!(f, "publish request denied"),
78            Self::ConnectRequestDenied => write!(f, "connect request denied"),
79            Self::InvalidChunkSize(size) => write!(f, "invalid chunk size: {}", size),
80            Self::PlayNotSupported => write!(f, "play not supported"),
81            Self::PublisherDropped => write!(f, "publisher dropped"),
82            Self::Timeout(error) => write!(f, "timeout: {}", error),
83        }
84    }
85}