passcod_web_transport_quinn/
error.rs1use std::sync::Arc;
2
3use thiserror::Error;
4
5use crate::{ConnectError, SettingsError};
6use quinn::rustls;
7
8#[derive(Error, Debug, Clone)]
10pub enum ClientError {
11 #[error("unexpected end of stream")]
12 UnexpectedEnd,
13
14 #[error("connection error: {0}")]
15 Connection(#[from] quinn::ConnectionError),
16
17 #[error("failed to write: {0}")]
18 WriteError(#[from] quinn::WriteError),
19
20 #[error("failed to read: {0}")]
21 ReadError(#[from] quinn::ReadError),
22
23 #[error("failed to exchange h3 settings: {0}")]
24 SettingsError(#[from] SettingsError),
25
26 #[error("failed to exchange h3 connect: {0}")]
27 HttpError(#[from] ConnectError),
28
29 #[error("quic error: {0}")]
30 QuinnError(#[from] quinn::ConnectError),
31
32 #[error("invalid DNS name: {0}")]
33 InvalidDnsName(String),
34
35 #[error("rustls error: {0}")]
36 Rustls(#[from] rustls::Error),
37}
38
39#[derive(Clone, Error, Debug)]
41pub enum SessionError {
42 #[error("connection error: {0}")]
43 ConnectionError(#[from] quinn::ConnectionError),
44
45 #[error("webtransport error: {0}")]
46 WebTransportError(#[from] WebTransportError),
47
48 #[error("send datagram error: {0}")]
49 SendDatagramError(#[from] quinn::SendDatagramError),
50}
51
52#[derive(Clone, Error, Debug)]
54pub enum WebTransportError {
55 #[error("unknown session")]
56 UnknownSession,
57
58 #[error("read error: {0}")]
59 ReadError(#[from] quinn::ReadExactError),
60
61 #[error("write error: {0}")]
62 WriteError(#[from] quinn::WriteError),
63}
64
65#[derive(Clone, Error, Debug)]
67pub enum WriteError {
68 #[error("STOP_SENDING: {0}")]
69 Stopped(u32),
70
71 #[error("invalid STOP_SENDING: {0}")]
72 InvalidStopped(quinn::VarInt),
73
74 #[error("session error: {0}")]
75 SessionError(#[from] SessionError),
76
77 #[error("stream closed")]
78 ClosedStream,
79}
80
81impl From<quinn::WriteError> for WriteError {
82 fn from(e: quinn::WriteError) -> Self {
83 match e {
84 quinn::WriteError::Stopped(code) => {
85 match web_transport_proto::error_from_http3(code.into_inner()) {
86 Some(code) => WriteError::Stopped(code),
87 None => WriteError::InvalidStopped(code),
88 }
89 }
90 quinn::WriteError::ClosedStream => WriteError::ClosedStream,
91 quinn::WriteError::ConnectionLost(e) => WriteError::SessionError(e.into()),
92 quinn::WriteError::ZeroRttRejected => unreachable!("0-RTT not supported"),
93 }
94 }
95}
96
97#[derive(Clone, Error, Debug)]
99pub enum ReadError {
100 #[error("session error: {0}")]
101 SessionError(#[from] SessionError),
102
103 #[error("RESET_STREAM: {0}")]
104 Reset(u32),
105
106 #[error("invalid RESET_STREAM: {0}")]
107 InvalidReset(quinn::VarInt),
108
109 #[error("stream already closed")]
110 ClosedStream,
111
112 #[error("ordered read on unordered stream")]
113 IllegalOrderedRead,
114}
115
116impl From<quinn::ReadError> for ReadError {
117 fn from(value: quinn::ReadError) -> Self {
118 match value {
119 quinn::ReadError::Reset(code) => {
120 match web_transport_proto::error_from_http3(code.into_inner()) {
121 Some(code) => ReadError::Reset(code),
122 None => ReadError::InvalidReset(code),
123 }
124 }
125 quinn::ReadError::ConnectionLost(e) => ReadError::SessionError(e.into()),
126 quinn::ReadError::IllegalOrderedRead => ReadError::IllegalOrderedRead,
127 quinn::ReadError::ClosedStream => ReadError::ClosedStream,
128 quinn::ReadError::ZeroRttRejected => unreachable!("0-RTT not supported"),
129 }
130 }
131}
132
133#[derive(Clone, Error, Debug)]
135pub enum ReadExactError {
136 #[error("finished early")]
137 FinishedEarly(usize),
138
139 #[error("read error: {0}")]
140 ReadError(#[from] ReadError),
141}
142
143impl From<quinn::ReadExactError> for ReadExactError {
144 fn from(e: quinn::ReadExactError) -> Self {
145 match e {
146 quinn::ReadExactError::FinishedEarly(size) => ReadExactError::FinishedEarly(size),
147 quinn::ReadExactError::ReadError(e) => ReadExactError::ReadError(e.into()),
148 }
149 }
150}
151
152#[derive(Clone, Error, Debug)]
154pub enum ReadToEndError {
155 #[error("too long")]
156 TooLong,
157
158 #[error("read error: {0}")]
159 ReadError(#[from] ReadError),
160}
161
162impl From<quinn::ReadToEndError> for ReadToEndError {
163 fn from(e: quinn::ReadToEndError) -> Self {
164 match e {
165 quinn::ReadToEndError::TooLong => ReadToEndError::TooLong,
166 quinn::ReadToEndError::Read(e) => ReadToEndError::ReadError(e.into()),
167 }
168 }
169}
170
171#[derive(Clone, Error, Debug)]
173#[error("stream closed")]
174pub struct ClosedStream;
175
176impl From<quinn::ClosedStream> for ClosedStream {
177 fn from(_: quinn::ClosedStream) -> Self {
178 ClosedStream
179 }
180}
181
182#[derive(Clone, Error, Debug)]
184pub enum StoppedError {
185 #[error("session error: {0}")]
186 SessionError(#[from] SessionError),
187
188 #[error("stream already closed")]
189 Closed,
190}
191
192impl From<quinn::StoppedError> for StoppedError {
193 fn from(e: quinn::StoppedError) -> Self {
194 match e {
195 quinn::StoppedError::ConnectionLost(e) => StoppedError::SessionError(e.into()),
196 quinn::StoppedError::ZeroRttRejected => unreachable!("0-RTT not supported"),
197 }
198 }
199}
200
201#[derive(Error, Debug, Clone)]
203pub enum ServerError {
204 #[error("unexpected end of stream")]
205 UnexpectedEnd,
206
207 #[error("connection error")]
208 Connection(#[from] quinn::ConnectionError),
209
210 #[error("failed to write")]
211 WriteError(#[from] quinn::WriteError),
212
213 #[error("failed to read")]
214 ReadError(#[from] quinn::ReadError),
215
216 #[error("failed to exchange h3 settings")]
217 SettingsError(#[from] SettingsError),
218
219 #[error("failed to exchange h3 connect")]
220 ConnectError(#[from] ConnectError),
221
222 #[error("io error: {0}")]
223 IoError(Arc<std::io::Error>),
224
225 #[error("rustls error: {0}")]
226 Rustls(#[from] rustls::Error),
227}
228
229