Skip to main content

rtsp/
error.rs

1//! Error types for the RTSP server library.
2
3use std::fmt;
4
5/// Errors that can occur in the RTSP server library.
6///
7/// Variants map to specific failure modes across the stack:
8///
9/// - **Protocol**: [`Parse`](Self::Parse) — malformed RTSP messages.
10/// - **Transport**: [`Io`](Self::Io) — socket/network failures.
11/// - **Session**: [`SessionNotFound`](Self::SessionNotFound),
12///   [`SessionNotPlaying`](Self::SessionNotPlaying),
13///   [`TransportNotConfigured`](Self::TransportNotConfigured).
14/// - **Server**: [`NotStarted`](Self::NotStarted),
15///   [`AlreadyRunning`](Self::AlreadyRunning).
16/// - **Mount**: [`MountNotFound`](Self::MountNotFound).
17/// - **Server**: [`InvalidBindAddress`](Self::InvalidBindAddress) — bind address must have an explicit non-zero port.
18#[derive(Debug, thiserror::Error)]
19pub enum RtspError {
20    /// Underlying I/O or socket error.
21    #[error("I/O error: {0}")]
22    Io(#[from] std::io::Error),
23
24    /// Bind address must be `host:port` with an explicit non-zero port (port 0 is not allowed).
25    #[error("invalid bind address: {0}")]
26    InvalidBindAddress(String),
27
28    /// No session with the given ID exists in the [`SessionManager`](crate::session::SessionManager).
29    #[error("session not found: {0}")]
30    SessionNotFound(String),
31
32    /// SETUP has not been completed for this session (no UDP ports negotiated).
33    #[error("transport not configured for session: {0}")]
34    TransportNotConfigured(String),
35
36    /// Attempted to send media to a session that is not in the Playing state.
37    #[error("session not in playing state: {0}")]
38    SessionNotPlaying(String),
39
40    /// [`Server::start`](crate::Server::start) has not been called yet.
41    #[error("server not started")]
42    NotStarted,
43
44    /// [`Server::start`](crate::Server::start) was called while already running.
45    #[error("server already running")]
46    AlreadyRunning,
47
48    /// Failed to parse an RTSP request message (RFC 2326 §6).
49    #[error("RTSP parse error: {kind}")]
50    Parse { kind: ParseErrorKind },
51
52    /// Server-side UDP port allocation exhausted the 5000–65534 range.
53    #[error("port range exhausted (tried to allocate beyond u16 range)")]
54    PortRangeExhausted,
55
56    /// No mount registered at the requested path.
57    #[error("mount not found: {0}")]
58    MountNotFound(String),
59}
60
61/// Specific kind of RTSP parse failure.
62#[derive(Debug)]
63pub enum ParseErrorKind {
64    /// Input was empty (no request line).
65    EmptyRequest,
66    /// Request line did not have the expected `Method URI Version` format.
67    InvalidRequestLine,
68    /// A header line did not contain a colon separator.
69    InvalidHeader,
70}
71
72impl fmt::Display for ParseErrorKind {
73    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74        match self {
75            Self::EmptyRequest => write!(f, "empty request"),
76            Self::InvalidRequestLine => write!(f, "invalid request line"),
77            Self::InvalidHeader => write!(f, "invalid header"),
78        }
79    }
80}
81
82/// Convenience alias for `Result<T, RtspError>`.
83pub type Result<T> = std::result::Result<T, RtspError>;