1use std::{fmt, io};
20
21use thiserror::Error;
22
23use crate::proto::serialize::txt::ParseError;
24#[cfg(feature = "backtrace")]
25use crate::proto::{ExtBacktrace, trace};
26use crate::proto::{ProtoError, ProtoErrorKind};
27
28#[derive(Debug, Error)]
30#[non_exhaustive]
31pub enum PersistenceErrorKind {
32 #[error("error recovering from journal: {}", _0)]
34 Recovery(&'static str),
35
36 #[error("wrong insert count: {} expect: {}", got, expect)]
38 WrongInsertCount {
39 got: usize,
41 expect: usize,
43 },
44
45 #[error("proto error: {0}")]
48 Proto(#[from] ProtoError),
49
50 #[cfg(feature = "sqlite")]
52 #[error("sqlite error: {0}")]
53 Sqlite(#[from] rusqlite::Error),
54
55 #[error("request timed out")]
57 Timeout,
58}
59
60#[derive(Debug, Error)]
62pub struct PersistenceError {
63 kind: PersistenceErrorKind,
64 #[cfg(feature = "backtrace")]
65 backtrack: Option<ExtBacktrace>,
66}
67
68impl PersistenceError {
69 pub fn kind(&self) -> &PersistenceErrorKind {
71 &self.kind
72 }
73}
74
75impl fmt::Display for PersistenceError {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 cfg_if::cfg_if! {
78 if #[cfg(feature = "backtrace")] {
79 if let Some(backtrace) = &self.backtrack {
80 fmt::Display::fmt(&self.kind, f)?;
81 fmt::Debug::fmt(backtrace, f)
82 } else {
83 fmt::Display::fmt(&self.kind, f)
84 }
85 } else {
86 fmt::Display::fmt(&self.kind, f)
87 }
88 }
89 }
90}
91
92impl From<PersistenceErrorKind> for PersistenceError {
93 fn from(kind: PersistenceErrorKind) -> Self {
94 Self {
95 kind,
96 #[cfg(feature = "backtrace")]
97 backtrack: trace!(),
98 }
99 }
100}
101
102impl From<ProtoError> for PersistenceError {
103 fn from(e: ProtoError) -> Self {
104 match e.kind() {
105 ProtoErrorKind::Timeout => PersistenceErrorKind::Timeout.into(),
106 _ => PersistenceErrorKind::from(e).into(),
107 }
108 }
109}
110
111#[cfg(feature = "sqlite")]
112impl From<rusqlite::Error> for PersistenceError {
113 fn from(e: rusqlite::Error) -> Self {
114 PersistenceErrorKind::from(e).into()
115 }
116}
117
118#[derive(Debug, Error)]
120#[non_exhaustive]
121pub enum ConfigErrorKind {
122 #[error("io error: {0}")]
125 Io(#[from] io::Error),
126
127 #[cfg(feature = "toml")]
129 #[error("toml decode error: {0}")]
130 TomlDecode(#[from] toml::de::Error),
131
132 #[error("failed to parse the zone file: {0}")]
134 ZoneParse(#[from] ParseError),
135}
136
137#[derive(Debug)]
139pub struct ConfigError {
140 kind: Box<ConfigErrorKind>,
141 #[cfg(feature = "backtrace")]
142 backtrack: Option<ExtBacktrace>,
143}
144
145impl ConfigError {
146 pub fn kind(&self) -> &ConfigErrorKind {
148 &self.kind
149 }
150}
151
152impl fmt::Display for ConfigError {
153 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154 cfg_if::cfg_if! {
155 if #[cfg(feature = "backtrace")] {
156 if let Some(backtrace) = &self.backtrack {
157 fmt::Display::fmt(&self.kind, f)?;
158 fmt::Debug::fmt(backtrace, f)
159 } else {
160 fmt::Display::fmt(&self.kind, f)
161 }
162 } else {
163 fmt::Display::fmt(&self.kind, f)
164 }
165 }
166 }
167}
168
169impl<E> From<E> for ConfigError
170where
171 E: Into<ConfigErrorKind>,
172{
173 fn from(error: E) -> Self {
174 let kind: ConfigErrorKind = error.into();
175
176 Self {
177 kind: Box::new(kind),
178 #[cfg(feature = "backtrace")]
179 backtrack: trace!(),
180 }
181 }
182}