Skip to content

Commit dc91d71

Browse files
committed
fix: more edge casing in error function
1 parent bc9620c commit dc91d71

File tree

2 files changed

+66
-26
lines changed

2 files changed

+66
-26
lines changed

src/dns/authority.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use anyhow::{anyhow, Result};
22
use futures_util::TryFutureExt;
3+
use std::io::{Error as IoError, ErrorKind};
34
use std::net::IpAddr::V4;
45
use std::str::FromStr;
56
use std::sync::Arc;
@@ -218,7 +219,7 @@ impl<F: DomainFacade + CertFacade + Send + Sync + 'static> AuthorityObject
218219
let txt = match authority.facade.find_domain_by_id(&first).await {
219220
Ok(Some(Domain { txt: Some(txt), .. })) => txt,
220221
Ok(Some(Domain { txt: None, .. })) => return Ok(LookupRecords::Empty),
221-
Ok(None) => return Err(error(anyhow!("Not found"))),
222+
Ok(None) => return Err(error(IoError::from(ErrorKind::NotFound))),
222223
Err(e) => return Err(error(e)),
223224
};
224225
let txt = TXT::new(vec![txt]);

src/util.rs

Lines changed: 64 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use anyhow::Error;
22
use std::any::Any;
3+
use std::error::Error as StdError;
34
use std::fmt::{Debug, Display};
45
use std::io::{Error as IoError, ErrorKind};
56
use std::time::{SystemTime, UNIX_EPOCH};
@@ -20,35 +21,35 @@ pub fn now() -> u64 {
2021
.as_secs()
2122
}
2223

23-
// E allows all StdError + Send + Sync + 'static or AnyhowError as this can only be constructed from the former
2424
pub(crate) fn error<I, E>(err: I) -> E
2525
where
26-
I: Into<Error> + 'static,
26+
I: Into<Box<dyn StdError + Send + Sync>> + 'static,
2727
E: From<IoError> + Display + Debug + Send + Sync + 'static,
2828
{
29-
// specialization if error is E or IoError
30-
// gets optimized away at compile time
3129
let mut err = Some(err);
30+
3231
if let Some(err) = Any::downcast_mut::<Option<E>>(&mut err) {
3332
return err.take().unwrap();
3433
}
34+
3535
if let Some(err) = Any::downcast_mut::<Option<IoError>>(&mut err) {
3636
return err.take().unwrap().into();
3737
}
3838

39-
let err = err.unwrap().into();
40-
41-
let err = match err.downcast::<E>() {
42-
Ok(err) => return err,
43-
Err(err) => err,
44-
};
45-
46-
let err = match err.downcast::<IoError>() {
47-
Ok(err) => err,
48-
Err(err) => IoError::new(ErrorKind::Other, err),
49-
};
39+
if let Some(err) = Any::downcast_mut::<Option<Error>>(&mut err) {
40+
let err = match err.take().unwrap().downcast::<E>() {
41+
Ok(err) => return err,
42+
Err(err) => err,
43+
};
44+
45+
let err = match err.downcast::<IoError>() {
46+
Ok(err) => err,
47+
Err(err) => IoError::new(ErrorKind::Other, err),
48+
};
49+
return err.into();
50+
}
5051

51-
err.into()
52+
IoError::new(ErrorKind::Other, err.unwrap()).into()
5253
}
5354

5455
pub(crate) fn uuid() -> String {
@@ -57,7 +58,7 @@ pub(crate) fn uuid() -> String {
5758

5859
#[cfg(test)]
5960
mod tests {
60-
use anyhow::anyhow;
61+
use anyhow::{anyhow, Error};
6162
use std::io::{Error as IoError, ErrorKind};
6263
use std::thread;
6364
use std::time::Duration;
@@ -108,6 +109,17 @@ mod tests {
108109
}
109110
}
110111

112+
#[test]
113+
fn self_error_works() {
114+
let expected = acme_lib::Error::Other("Test".to_owned());
115+
116+
let actual = acme_lib::Error::Other("Test".to_owned());
117+
let actual: acme_lib::Error = error(actual);
118+
119+
assert_eq!(format!("{:?}", expected), format!("{:?}", actual));
120+
assert_eq!(format!("{}", expected), format!("{}", actual));
121+
}
122+
111123
#[test]
112124
fn io_error_works() {
113125
let expected = IoError::new(ErrorKind::InvalidData, "Hallo");
@@ -116,21 +128,48 @@ mod tests {
116128
let actual = extract_error(error(actual));
117129

118130
assert_eq!(format!("{:?}", expected), format!("{:?}", actual));
131+
assert_eq!(format!("{}", expected), format!("{}", actual));
119132
}
120133

121134
#[test]
122-
fn error_works() {
123-
let expected = anyhow!("test");
135+
fn anyhow_works() {
136+
let expected = acme_lib::Error::Other("Test".to_owned());
137+
138+
let actual = Error::new(acme_lib::Error::Other("Test".to_owned()));
139+
let actual: acme_lib::Error = error(actual);
140+
141+
assert_eq!(format!("{:?}", expected), format!("{:?}", actual));
142+
assert_eq!(format!("{}", expected), format!("{}", actual));
143+
}
144+
145+
#[test]
146+
fn anyhow_io_works() {
147+
let expected = IoError::from(ErrorKind::Other);
148+
149+
let actual = Error::new(IoError::from(ErrorKind::Other));
150+
let actual = extract_error(error(actual));
151+
152+
assert_eq!(format!("{:?}", expected), format!("{:?}", actual));
153+
assert_eq!(format!("{}", expected), format!("{}", actual));
154+
}
124155

125-
let actual = extract_error(error(anyhow!("test")));
156+
#[test]
157+
fn anyhow_error_works() {
158+
let expected = IoError::new(ErrorKind::Other, anyhow!("Test"));
126159

127-
assert_eq!(ErrorKind::Other, actual.kind());
160+
let actual = extract_error(error(anyhow!("Test")));
128161

129-
// is not equal because original error gets boxed in an io error
130-
assert_ne!(format!("{:?}", expected), format!("{:?}", actual));
162+
assert_eq!(format!("{:?}", expected), format!("{:?}", actual));
163+
assert_eq!(format!("{}", expected), format!("{}", actual));
164+
}
131165

132-
// here we access the actual inner error
133-
let actual = actual.into_inner().expect("Error has no inner error");
166+
#[test]
167+
fn error_works() {
168+
let expected = IoError::new(ErrorKind::Other, "Test");
169+
170+
let actual = extract_error(error("Test"));
171+
172+
assert_eq!(format!("{:?}", expected), format!("{:?}", actual));
134173
assert_eq!(format!("{}", expected), format!("{}", actual));
135174
}
136175
}

0 commit comments

Comments
 (0)