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}