rsrs_core/frame/
error.rs

1use derive_more::Display;
2use recode::bytes::BytesMut;
3use recode::codec::Unprefixed;
4use recode::util::EncoderExt;
5
6use crate::frame;
7
8frame! {
9    /// ERROR Frame (0x0B)
10    ///
11    /// Error frames are used for errors on individual requests/streams as
12    /// well as connection errors and in response to SETUP frames.
13    ///
14    /// # Frame Contents
15    ///
16    /// ```text
17    ///
18    ///  0                   1                   2                   3
19    ///  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
20    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
21    /// |                           Stream ID                           |
22    /// +-----------+-+-+---------------+-------------------------------+
23    /// |Frame Type |0|0|      Flags    |
24    /// +-----------+-+-+---------------+-------------------------------+
25    /// |                          Error Code                           |
26    /// +---------------------------------------------------------------+
27    ///                            Error Data
28    /// ```
29    ///
30    /// # Note
31    /// Unsed values in the range of 0x0001 to 0x00300 are reserved for future
32    /// protocol use. Values in the range of `0x00301` to `0xFFFFFFFE` are
33    /// reserved for application layer errors.
34    Error [header] {
35        #mask = [];
36
37        /// Type of Error.
38        ///
39        /// See [`ErrorCode`] of valid Error Codes.
40        pub error_code(required): ErrorCode;
41
42        /// Error Data
43        ///
44        /// Includes Payload describing error information. Error Data SHOULD b
45        /// a UTF-8 encoded string. The string MUST NOT be null terminated.
46        @with("Unprefixed");
47        pub data: BytesMut;
48    }
49}
50
51/// Valid error codes contained in [`Error`](self::Error) frames.
52#[derive(Debug, Clone, Display)]
53#[from_to_repr::from_to_other(base_type = u32)]
54pub enum ErrorCode {
55    /// The Setup frame is invalid for the server (it could be that the client
56    /// is too recent for the old server). Stream ID MUST be 0.
57    #[display(fmt = "INVALID_SETUP")]
58    InvalidSetup     = 0x00000001,
59
60    /// Some (or all) of the parameters specified by the client are unsupported
61    /// by the server. Stream ID MUST be 0.
62    #[display(fmt = "UNSUPPORTED_SETUP")]
63    UnsupportedSetup = 0x00000002,
64
65    /// The server rejected the setup, it can specify the reason in the
66    /// payload. Stream ID MUST be 0.
67    #[display(fmt = "REJECT_SETUP")]
68    RejectSetup      = 0x00000003,
69
70    /// The server rejected the resume, it can specify the reason in the
71    /// payload. Stream ID MUST be 0.
72    #[display(fmt = "REJECT_RESUME")]
73    RejectResume     = 0x00000004,
74
75    /// The connection is being terminated. Stream ID MUST be 0. Sender or
76    /// Receiver of this frame MAY close the connection immediately without
77    /// waiting for outstanding streams to terminate.
78    #[display(fmt = "CONNECTION_ERROR")]
79    ConnectionError  = 0x00000101,
80
81    /// The connection is being terminated. Stream ID MUST be 0. Sender or
82    /// Receiver of this frame MUST wait for outstanding streams to terminate
83    /// before closing the connection. New requests MAY not be accepted.
84    #[display(fmt = "CONNECTION_CLOSE")]
85    ConnectionClose  = 0x00000102,
86
87    /// Application layer logic generating a Reactive Streams onError event.
88    /// Stream ID MUST be > 0.
89    #[display(fmt = "APPLICATION_ERROR")]
90    ApplicationError = 0x00000201,
91
92    /// Despite being a valid request, the Responder decided to reject it. The
93    /// Responder guarantees that it didn't process the request. The reason for
94    /// the rejection is explained in the Error Data section.
95    /// Stream ID MUST be > 0.
96    #[display(fmt = "REJECTED")]
97    Rejected         = 0x00000202,
98
99    /// The Responder canceled the request but may have started processing it
100    /// (similar to REJECTED but doesn't guarantee lack of side-effects).
101    /// Stream ID MUST be > 0.
102    #[display(fmt = "CANCELED")]
103    Canceled         = 0x00000203,
104
105    /// The request is invalid. Stream ID MUST be > 0.
106    #[display(fmt = "INVALID")]
107    Invalid          = 0x00000204,
108
109    /// Reserved for Extension Use.
110    #[display(fmt = "UNKNOWN[{:08X}]", .0)]
111    Other(u32),
112}
113
114impl recode::Decoder for ErrorCode {
115    type Error = crate::Error;
116
117    #[inline]
118    fn decode(buf: &mut BytesMut) -> Result<Self, Self::Error> {
119        u32::decode(buf)
120            .map(ErrorCode::from_base_type)
121            .map_err(Into::into)
122    }
123}
124
125impl recode::Encoder for ErrorCode {
126    type Error = crate::Error;
127
128    #[inline]
129    fn encode(item: &Self, buf: &mut BytesMut) -> Result<(), Self::Error> {
130        item.to_base_type().encode_to(buf).map_err(Into::into)
131    }
132
133    #[inline]
134    fn size_of(item: &Self) -> usize {
135        item.size()
136    }
137}