tokio_dbus/
error.rs

1use std::error;
2use std::fmt;
3use std::io;
4use std::str::Utf8Error;
5
6use crate::connection::TransportState;
7use crate::ObjectPathError;
8use crate::Signature;
9use crate::SignatureError;
10
11/// Result alias using an [`Error`] as the error type by default.
12pub type Result<T, E = Error> = std::result::Result<T, E>;
13
14/// An error raised by this crate.
15#[derive(Debug)]
16pub struct Error {
17    kind: ErrorKind,
18}
19
20impl Error {
21    #[inline]
22    pub(crate) fn new(kind: ErrorKind) -> Error {
23        Self { kind }
24    }
25
26    /// Test if the error indicates that the operation would block.
27    #[inline]
28    pub(crate) fn would_block(&self) -> bool {
29        matches!(self.kind, ErrorKind::WouldBlock)
30    }
31}
32
33impl From<SignatureError> for Error {
34    #[inline]
35    fn from(error: SignatureError) -> Self {
36        Self::new(ErrorKind::Signature(error))
37    }
38}
39
40impl From<ObjectPathError> for Error {
41    #[inline]
42    fn from(error: ObjectPathError) -> Self {
43        Self::new(ErrorKind::ObjectPath(error))
44    }
45}
46
47impl From<io::Error> for Error {
48    #[inline]
49    fn from(error: io::Error) -> Self {
50        match error.kind() {
51            io::ErrorKind::WouldBlock => Self::new(ErrorKind::WouldBlock),
52            _ => Self::new(ErrorKind::Io(error)),
53        }
54    }
55}
56
57impl From<Utf8Error> for Error {
58    #[inline]
59    fn from(error: Utf8Error) -> Self {
60        Self::new(ErrorKind::Utf8Error(error))
61    }
62}
63
64impl From<ErrorKind> for Error {
65    #[inline]
66    fn from(kind: ErrorKind) -> Self {
67        Self::new(kind)
68    }
69}
70
71impl fmt::Display for Error {
72    #[inline]
73    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
74        match &self.kind {
75            ErrorKind::Io(..) => write!(f, "I/O error"),
76            ErrorKind::Signature(..) => write!(f, "Signature error"),
77            ErrorKind::ObjectPath(..) => write!(f, "ObjectPath error"),
78            ErrorKind::Utf8Error(..) => write!(f, "UTF-8 error"),
79            ErrorKind::WouldBlock => write!(f, "Would block"),
80            ErrorKind::BufferUnderflow => write!(f, "Buffer underflow"),
81            ErrorKind::MissingBus => write!(f, "Missing bus to connect to"),
82            ErrorKind::InvalidAddress => write!(f, "Invalid d-bus address"),
83            ErrorKind::InvalidSasl => write!(f, "Invalid SASL message"),
84            ErrorKind::InvalidSaslResponse => write!(f, "Invalid SASL command"),
85            ErrorKind::InvalidState(state) => write!(f, "Invalid connection state `{state}`"),
86            ErrorKind::InvalidProtocol => write!(f, "Invalid protocol"),
87            ErrorKind::MissingPath => write!(f, "Missing required PATH header"),
88            ErrorKind::MissingMember => write!(f, "Missing required MEMBER header"),
89            ErrorKind::MissingReplySerial => write!(f, "Missing required REPLY_SERIAL header"),
90            ErrorKind::ZeroSerial => write!(f, "Zero in header serial"),
91            ErrorKind::ZeroReplySerial => write!(f, "Zero REPLY_SERIAL header"),
92            ErrorKind::MissingErrorName => write!(f, "Missing required ERROR_NAME header"),
93            ErrorKind::NotNullTerminated => {
94                write!(f, "String is not null terminated")
95            }
96            ErrorKind::ArrayTooLong(length) => {
97                write!(f, "Array of length {length} is too long (max is 67108864)")
98            }
99            ErrorKind::BodyTooLong(length) => {
100                write!(f, "Body of length {length} is too long (max is 134217728)")
101            }
102            ErrorKind::MissingMessage => {
103                write!(f, "No message")
104            }
105            ErrorKind::ResponseError(error_name, message) => {
106                write!(f, "Response error: {error_name}: {message}")
107            }
108            ErrorKind::UnsupportedVariant(signature) => {
109                write!(f, "Unsupported variant {signature:?}")
110            }
111        }
112    }
113}
114
115impl error::Error for Error {
116    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
117        match &self.kind {
118            ErrorKind::Io(error) => Some(error),
119            ErrorKind::Signature(error) => Some(error),
120            ErrorKind::ObjectPath(error) => Some(error),
121            ErrorKind::Utf8Error(error) => Some(error),
122            _ => None,
123        }
124    }
125}
126
127#[derive(Debug)]
128pub(crate) enum ErrorKind {
129    Io(io::Error),
130    Signature(SignatureError),
131    ObjectPath(ObjectPathError),
132    Utf8Error(Utf8Error),
133    WouldBlock,
134    BufferUnderflow,
135    MissingBus,
136    InvalidAddress,
137    InvalidSasl,
138    InvalidSaslResponse,
139    InvalidState(TransportState),
140    InvalidProtocol,
141    MissingPath,
142    MissingMember,
143    MissingReplySerial,
144    ZeroSerial,
145    ZeroReplySerial,
146    MissingErrorName,
147    NotNullTerminated,
148    BodyTooLong(u32),
149    ArrayTooLong(u32),
150    MissingMessage,
151    UnsupportedVariant(Box<Signature>),
152    ResponseError(Box<str>, Box<str>),
153}