tiberius/
error.rs

1//! Error module
2pub use crate::tds::codec::TokenError;
3pub use std::io::ErrorKind as IoErrorKind;
4use std::{borrow::Cow, convert::Infallible, io};
5use thiserror::Error;
6
7/// A unified error enum that contains several errors that might occurr during
8/// the lifecycle of this driver
9#[derive(Debug, Clone, Error, PartialEq, Eq)]
10pub enum Error {
11    #[error("An error occured during the attempt of performing I/O: {}", message)]
12    /// An error occured when performing I/O to the server.
13    Io {
14        /// A list specifying general categories of I/O error.
15        kind: IoErrorKind,
16        /// The error description.
17        message: String,
18    },
19    #[error("Protocol error: {}", _0)]
20    /// An error happened during the request or response parsing.
21    Protocol(Cow<'static, str>),
22    #[error("Encoding error: {}", _0)]
23    /// Server responded with encoding not supported.
24    Encoding(Cow<'static, str>),
25    #[error("Conversion error: {}", _0)]
26    /// Conversion failure from one type to another.
27    Conversion(Cow<'static, str>),
28    #[error("UTF-8 error")]
29    /// Tried to convert data to UTF-8 that was not valid.
30    Utf8,
31    #[error("UTF-16 error")]
32    /// Tried to convert data to UTF-16 that was not valid.
33    Utf16,
34    #[error("Error parsing an integer: {}", _0)]
35    /// Tried to parse an integer that was not an integer.
36    ParseInt(std::num::ParseIntError),
37    #[error("Token error: {}", _0)]
38    /// An error returned by the server.
39    Server(TokenError),
40    #[error("Error forming TLS connection: {}", _0)]
41    /// An error in the TLS handshake.
42    Tls(String),
43    #[cfg(any(all(unix, feature = "integrated-auth-gssapi"), doc))]
44    #[cfg_attr(
45        feature = "docs",
46        doc(cfg(all(unix, feature = "integrated-auth-gssapi")))
47    )]
48    /// An error from the GSSAPI library.
49    #[error("GSSAPI Error: {}", _0)]
50    Gssapi(String),
51    #[error(
52        "Server requested a connection to an alternative address: `{}:{}`",
53        host,
54        port
55    )]
56    /// Server requested a connection to an alternative address.
57    Routing {
58        /// The requested hostname
59        host: String,
60        /// The requested port.
61        port: u16,
62    },
63    #[error("BULK UPLOAD input failure: {0}")]
64    /// Invalid input in Bulk Upload
65    BulkInput(Cow<'static, str>),
66}
67
68impl Error {
69    /// True, if the error was caused by a deadlock.
70    pub fn is_deadlock(&self) -> bool {
71        self.code().map(|c| c == 1205).unwrap_or(false)
72    }
73
74    /// Returns the error code, if the error originates from the
75    /// server.
76    pub fn code(&self) -> Option<u32> {
77        match self {
78            Error::Server(e) => Some(e.code()),
79            _ => None,
80        }
81    }
82}
83
84impl From<uuid::Error> for Error {
85    fn from(e: uuid::Error) -> Self {
86        Self::Conversion(format!("Error convertiong a Guid value {}", e).into())
87    }
88}
89
90#[cfg(feature = "native-tls")]
91impl From<async_native_tls::Error> for Error {
92    fn from(v: async_native_tls::Error) -> Self {
93        Error::Tls(format!("{}", v))
94    }
95}
96
97#[cfg(feature = "vendored-openssl")]
98impl From<opentls::Error> for Error {
99    fn from(v: opentls::Error) -> Self {
100        Error::Tls(format!("{}", v))
101    }
102}
103
104impl From<Infallible> for Error {
105    fn from(_: Infallible) -> Self {
106        unreachable!()
107    }
108}
109
110impl From<io::Error> for Error {
111    fn from(err: io::Error) -> Error {
112        Self::Io {
113            kind: err.kind(),
114            message: format!("{}", err),
115        }
116    }
117}
118
119impl From<std::num::ParseIntError> for Error {
120    fn from(err: std::num::ParseIntError) -> Error {
121        Error::ParseInt(err)
122    }
123}
124
125impl From<std::str::Utf8Error> for Error {
126    fn from(_: std::str::Utf8Error) -> Error {
127        Error::Utf8
128    }
129}
130
131impl From<std::string::FromUtf8Error> for Error {
132    fn from(_err: std::string::FromUtf8Error) -> Error {
133        Error::Utf8
134    }
135}
136
137impl From<std::string::FromUtf16Error> for Error {
138    fn from(_err: std::string::FromUtf16Error) -> Error {
139        Error::Utf16
140    }
141}
142
143impl From<connection_string::Error> for Error {
144    fn from(err: connection_string::Error) -> Error {
145        let err = Cow::Owned(format!("{}", err));
146        Error::Conversion(err)
147    }
148}
149
150#[cfg(all(unix, feature = "integrated-auth-gssapi"))]
151#[cfg_attr(
152    feature = "docs",
153    doc(cfg(all(unix, feature = "integrated-auth-gssapi")))
154)]
155impl From<libgssapi::error::Error> for Error {
156    fn from(err: libgssapi::error::Error) -> Error {
157        Error::Gssapi(format!("{}", err))
158    }
159}