xref: /webrtc/util/src/error.rs (revision ffe74184)
1*ffe74184SMartin Algesten #![allow(dead_code)]
2*ffe74184SMartin Algesten 
3*ffe74184SMartin Algesten use std::io;
4*ffe74184SMartin Algesten use std::net;
5*ffe74184SMartin Algesten use std::num::ParseIntError;
6*ffe74184SMartin Algesten use std::string::FromUtf8Error;
7*ffe74184SMartin Algesten use thiserror::Error;
8*ffe74184SMartin Algesten 
9*ffe74184SMartin Algesten pub type Result<T> = std::result::Result<T, Error>;
10*ffe74184SMartin Algesten 
11*ffe74184SMartin Algesten #[derive(Error, Debug, PartialEq)]
12*ffe74184SMartin Algesten #[non_exhaustive]
13*ffe74184SMartin Algesten pub enum Error {
14*ffe74184SMartin Algesten     #[error("buffer: full")]
15*ffe74184SMartin Algesten     ErrBufferFull,
16*ffe74184SMartin Algesten     #[error("buffer: closed")]
17*ffe74184SMartin Algesten     ErrBufferClosed,
18*ffe74184SMartin Algesten     #[error("buffer: short")]
19*ffe74184SMartin Algesten     ErrBufferShort,
20*ffe74184SMartin Algesten     #[error("packet too big")]
21*ffe74184SMartin Algesten     ErrPacketTooBig,
22*ffe74184SMartin Algesten     #[error("i/o timeout")]
23*ffe74184SMartin Algesten     ErrTimeout,
24*ffe74184SMartin Algesten     #[error("udp: listener closed")]
25*ffe74184SMartin Algesten     ErrClosedListener,
26*ffe74184SMartin Algesten     #[error("udp: listen queue exceeded")]
27*ffe74184SMartin Algesten     ErrListenQueueExceeded,
28*ffe74184SMartin Algesten     #[error("udp: listener accept ch closed")]
29*ffe74184SMartin Algesten     ErrClosedListenerAcceptCh,
30*ffe74184SMartin Algesten     #[error("obs cannot be nil")]
31*ffe74184SMartin Algesten     ErrObsCannotBeNil,
32*ffe74184SMartin Algesten     #[error("se of closed network connection")]
33*ffe74184SMartin Algesten     ErrUseClosedNetworkConn,
34*ffe74184SMartin Algesten     #[error("addr is not a net.UDPAddr")]
35*ffe74184SMartin Algesten     ErrAddrNotUdpAddr,
36*ffe74184SMartin Algesten     #[error("something went wrong with locAddr")]
37*ffe74184SMartin Algesten     ErrLocAddr,
38*ffe74184SMartin Algesten     #[error("already closed")]
39*ffe74184SMartin Algesten     ErrAlreadyClosed,
40*ffe74184SMartin Algesten     #[error("no remAddr defined")]
41*ffe74184SMartin Algesten     ErrNoRemAddr,
42*ffe74184SMartin Algesten     #[error("address already in use")]
43*ffe74184SMartin Algesten     ErrAddressAlreadyInUse,
44*ffe74184SMartin Algesten     #[error("no such UDPConn")]
45*ffe74184SMartin Algesten     ErrNoSuchUdpConn,
46*ffe74184SMartin Algesten     #[error("cannot remove unspecified IP by the specified IP")]
47*ffe74184SMartin Algesten     ErrCannotRemoveUnspecifiedIp,
48*ffe74184SMartin Algesten     #[error("no address assigned")]
49*ffe74184SMartin Algesten     ErrNoAddressAssigned,
50*ffe74184SMartin Algesten     #[error("1:1 NAT requires more than one mapping")]
51*ffe74184SMartin Algesten     ErrNatRequriesMapping,
52*ffe74184SMartin Algesten     #[error("length mismtach between mappedIPs and localIPs")]
53*ffe74184SMartin Algesten     ErrMismatchLengthIp,
54*ffe74184SMartin Algesten     #[error("non-udp translation is not supported yet")]
55*ffe74184SMartin Algesten     ErrNonUdpTranslationNotSupported,
56*ffe74184SMartin Algesten     #[error("no associated local address")]
57*ffe74184SMartin Algesten     ErrNoAssociatedLocalAddress,
58*ffe74184SMartin Algesten     #[error("no NAT binding found")]
59*ffe74184SMartin Algesten     ErrNoNatBindingFound,
60*ffe74184SMartin Algesten     #[error("has no permission")]
61*ffe74184SMartin Algesten     ErrHasNoPermission,
62*ffe74184SMartin Algesten     #[error("host name must not be empty")]
63*ffe74184SMartin Algesten     ErrHostnameEmpty,
64*ffe74184SMartin Algesten     #[error("failed to parse IP address")]
65*ffe74184SMartin Algesten     ErrFailedToParseIpaddr,
66*ffe74184SMartin Algesten     #[error("no interface is available")]
67*ffe74184SMartin Algesten     ErrNoInterface,
68*ffe74184SMartin Algesten     #[error("not found")]
69*ffe74184SMartin Algesten     ErrNotFound,
70*ffe74184SMartin Algesten     #[error("unexpected network")]
71*ffe74184SMartin Algesten     ErrUnexpectedNetwork,
72*ffe74184SMartin Algesten     #[error("can't assign requested address")]
73*ffe74184SMartin Algesten     ErrCantAssignRequestedAddr,
74*ffe74184SMartin Algesten     #[error("unknown network")]
75*ffe74184SMartin Algesten     ErrUnknownNetwork,
76*ffe74184SMartin Algesten     #[error("no router linked")]
77*ffe74184SMartin Algesten     ErrNoRouterLinked,
78*ffe74184SMartin Algesten     #[error("invalid port number")]
79*ffe74184SMartin Algesten     ErrInvalidPortNumber,
80*ffe74184SMartin Algesten     #[error("unexpected type-switch failure")]
81*ffe74184SMartin Algesten     ErrUnexpectedTypeSwitchFailure,
82*ffe74184SMartin Algesten     #[error("bind failed")]
83*ffe74184SMartin Algesten     ErrBindFailed,
84*ffe74184SMartin Algesten     #[error("end port is less than the start")]
85*ffe74184SMartin Algesten     ErrEndPortLessThanStart,
86*ffe74184SMartin Algesten     #[error("port space exhausted")]
87*ffe74184SMartin Algesten     ErrPortSpaceExhausted,
88*ffe74184SMartin Algesten     #[error("vnet is not enabled")]
89*ffe74184SMartin Algesten     ErrVnetDisabled,
90*ffe74184SMartin Algesten     #[error("invalid local IP in static_ips")]
91*ffe74184SMartin Algesten     ErrInvalidLocalIpInStaticIps,
92*ffe74184SMartin Algesten     #[error("mapped in static_ips is beyond subnet")]
93*ffe74184SMartin Algesten     ErrLocalIpBeyondStaticIpsSubset,
94*ffe74184SMartin Algesten     #[error("all static_ips must have associated local IPs")]
95*ffe74184SMartin Algesten     ErrLocalIpNoStaticsIpsAssociated,
96*ffe74184SMartin Algesten     #[error("router already started")]
97*ffe74184SMartin Algesten     ErrRouterAlreadyStarted,
98*ffe74184SMartin Algesten     #[error("router already stopped")]
99*ffe74184SMartin Algesten     ErrRouterAlreadyStopped,
100*ffe74184SMartin Algesten     #[error("static IP is beyond subnet")]
101*ffe74184SMartin Algesten     ErrStaticIpIsBeyondSubnet,
102*ffe74184SMartin Algesten     #[error("address space exhausted")]
103*ffe74184SMartin Algesten     ErrAddressSpaceExhausted,
104*ffe74184SMartin Algesten     #[error("no IP address is assigned for eth0")]
105*ffe74184SMartin Algesten     ErrNoIpaddrEth0,
106*ffe74184SMartin Algesten     #[error("Invalid mask")]
107*ffe74184SMartin Algesten     ErrInvalidMask,
108*ffe74184SMartin Algesten     #[error("parse ipnet: {0}")]
109*ffe74184SMartin Algesten     ParseIpnet(#[from] ipnet::AddrParseError),
110*ffe74184SMartin Algesten     #[error("parse ip: {0}")]
111*ffe74184SMartin Algesten     ParseIp(#[from] net::AddrParseError),
112*ffe74184SMartin Algesten     #[error("parse int: {0}")]
113*ffe74184SMartin Algesten     ParseInt(#[from] ParseIntError),
114*ffe74184SMartin Algesten     #[error("{0}")]
115*ffe74184SMartin Algesten     Io(#[source] IoError),
116*ffe74184SMartin Algesten     #[error("utf8: {0}")]
117*ffe74184SMartin Algesten     Utf8(#[from] FromUtf8Error),
118*ffe74184SMartin Algesten     #[error("{0}")]
119*ffe74184SMartin Algesten     Std(#[source] StdError),
120*ffe74184SMartin Algesten     #[error("{0}")]
121*ffe74184SMartin Algesten     Other(String),
122*ffe74184SMartin Algesten }
123*ffe74184SMartin Algesten 
124*ffe74184SMartin Algesten impl Error {
from_std<T>(error: T) -> Self where T: std::error::Error + Send + Sync + 'static,125*ffe74184SMartin Algesten     pub fn from_std<T>(error: T) -> Self
126*ffe74184SMartin Algesten     where
127*ffe74184SMartin Algesten         T: std::error::Error + Send + Sync + 'static,
128*ffe74184SMartin Algesten     {
129*ffe74184SMartin Algesten         Error::Std(StdError(Box::new(error)))
130*ffe74184SMartin Algesten     }
131*ffe74184SMartin Algesten 
downcast_ref<T: std::error::Error + 'static>(&self) -> Option<&T>132*ffe74184SMartin Algesten     pub fn downcast_ref<T: std::error::Error + 'static>(&self) -> Option<&T> {
133*ffe74184SMartin Algesten         if let Error::Std(s) = self {
134*ffe74184SMartin Algesten             return s.0.downcast_ref();
135*ffe74184SMartin Algesten         }
136*ffe74184SMartin Algesten 
137*ffe74184SMartin Algesten         None
138*ffe74184SMartin Algesten     }
139*ffe74184SMartin Algesten }
140*ffe74184SMartin Algesten 
141*ffe74184SMartin Algesten #[derive(Debug, Error)]
142*ffe74184SMartin Algesten #[error("io error: {0}")]
143*ffe74184SMartin Algesten pub struct IoError(#[from] pub io::Error);
144*ffe74184SMartin Algesten 
145*ffe74184SMartin Algesten // Workaround for wanting PartialEq for io::Error.
146*ffe74184SMartin Algesten impl PartialEq for IoError {
eq(&self, other: &Self) -> bool147*ffe74184SMartin Algesten     fn eq(&self, other: &Self) -> bool {
148*ffe74184SMartin Algesten         self.0.kind() == other.0.kind()
149*ffe74184SMartin Algesten     }
150*ffe74184SMartin Algesten }
151*ffe74184SMartin Algesten 
152*ffe74184SMartin Algesten impl From<io::Error> for Error {
from(e: io::Error) -> Self153*ffe74184SMartin Algesten     fn from(e: io::Error) -> Self {
154*ffe74184SMartin Algesten         Error::Io(IoError(e))
155*ffe74184SMartin Algesten     }
156*ffe74184SMartin Algesten }
157*ffe74184SMartin Algesten 
158*ffe74184SMartin Algesten /// An escape hatch to preserve stack traces when we don't know the error.
159*ffe74184SMartin Algesten ///
160*ffe74184SMartin Algesten /// This crate exports some traits such as `Conn` and `Listener`. The trait functions
161*ffe74184SMartin Algesten /// produce the local error `util::Error`. However when used in crates higher up the stack,
162*ffe74184SMartin Algesten /// we are forced to handle errors that are local to that crate. For example we use
163*ffe74184SMartin Algesten /// `Listener` the `dtls` crate and it needs to handle `dtls::Error`.
164*ffe74184SMartin Algesten ///
165*ffe74184SMartin Algesten /// By using `util::Error::from_std` we can preserve the underlying error (and stack trace!).
166*ffe74184SMartin Algesten #[derive(Debug, Error)]
167*ffe74184SMartin Algesten #[error("{0}")]
168*ffe74184SMartin Algesten pub struct StdError(pub Box<dyn std::error::Error + Send + Sync>);
169*ffe74184SMartin Algesten 
170*ffe74184SMartin Algesten impl PartialEq for StdError {
eq(&self, _: &Self) -> bool171*ffe74184SMartin Algesten     fn eq(&self, _: &Self) -> bool {
172*ffe74184SMartin Algesten         false
173*ffe74184SMartin Algesten     }
174*ffe74184SMartin Algesten }
175