1use thiserror::Error;
2
3pub use color_eyre::eyre::eyre;
4
5use crate::protocol::{response::ErrPayload, response::ErrPayloadBytes};
6
7pub type Result<T> = core::result::Result<T, Error>;
8
9#[derive(Debug, Error)]
10pub enum Error {
11 #[error("Server Error: {0}")]
13 ServerError(#[from] ErrPayload),
14 #[error(
16 "Connection mismatch: transaction started on connection {expected}, but commit/rollback called on connection {actual}"
17 )]
18 ConnectionMismatch { expected: u64, actual: u64 },
19 #[error("Bad usage error: {0}")]
20 BadUsageError(String),
21 #[error("IO error: {0}")]
23 IoError(#[from] std::io::Error),
24 #[error("A bug in zero-mysql: {0}")]
26 LibraryBug(#[from] color_eyre::Report),
27 #[error("Unsupported authentication plugin: {0}")]
28 Unsupported(String),
29 #[error("Cannot nest transactions - a transaction is already active")]
30 NestedTransaction,
31}
32
33impl<'buf> From<ErrPayloadBytes<'buf>> for Error {
34 fn from(value: ErrPayloadBytes) -> Self {
35 match ErrPayload::try_from(value) {
36 Ok(err_payload) => Error::ServerError(err_payload),
37 Err(err) => err,
38 }
39 }
40}
41
42impl From<core::convert::Infallible> for Error {
43 fn from(err: core::convert::Infallible) -> Self {
44 match err {}
45 }
46}
47
48impl Error {
49 pub fn from_debug(err: impl std::fmt::Debug) -> Self {
50 Self::LibraryBug(color_eyre::eyre::eyre!(format!("{:#?}", err)))
51 }
52
53 pub fn is_conn_broken(&self) -> bool {
57 match self {
58 Error::ServerError(err_payload) => {
59 match err_payload.sql_state.as_str() {
60 "23000" => false,
62 "22001" | "22003" | "22007" | "22012" => false,
64 "42000" | "42S02" | "42S22" => false,
66 "0A000" => false,
68 _ => true,
70 }
71 }
72 _ => true,
74 }
75 }
76}
77
78impl<Src, Dst: ?Sized> From<zerocopy::CastError<Src, Dst>> for Error {
79 fn from(err: zerocopy::CastError<Src, Dst>) -> Self {
80 Self::LibraryBug(color_eyre::eyre::eyre!("{:#?}", err))
81 }
82}