Skip to content

Commit f7fd481

Browse files
Fishrock123jbr
andcommitted
crate: add features to switch Error backend
Allows end users to choose between anyhow and eyre. Co-Authored-By: Jacob Rothstein <[email protected]>
1 parent 18b86df commit f7fd481

File tree

3 files changed

+50
-10
lines changed

3 files changed

+50
-10
lines changed

Cargo.toml

+10-3
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,26 @@ features = ["docs"]
1616
rustdoc-args = ["--cfg", "feature=\"docs\""]
1717

1818
[features]
19-
default = ["fs", "cookie-secure"]
19+
default = ["error_anyhow", "fs", "cookie-secure"]
2020
docs = ["unstable"]
21+
error_anyhow = ["anyhow"]
22+
error_eyre = ["eyre", "stable-eyre"]
2123
unstable = []
2224
hyperium_http = ["http"]
2325
async_std = ["fs"]
2426
cookie-secure = ["cookie/secure"]
2527
fs = ["async-std"]
2628

2729
[dependencies]
30+
# features: error_anyhow
31+
anyhow = { version = "1.0.26", optional = true }
2832
# features: async_std
2933
async-std = { version = "1.6.0", optional = true }
3034
futures-lite = "1.11.1"
3135
async-channel = "1.5.1"
3236

3337
# features: hyperium/http
3438
http = { version = "0.2.0", optional = true }
35-
36-
anyhow = "1.0.26"
3739
cookie = { version = "0.14.0", features = ["percent-encode"] }
3840
infer = "0.2.3"
3941
pin-project-lite = "0.1.0"
@@ -44,6 +46,11 @@ serde_urlencoded = "0.7.0"
4446
rand = "0.7.3"
4547
serde_qs = "0.7.0"
4648
base64 = "0.13.0"
49+
backtrace = "0.3.50"
50+
51+
# features: error_anyhow
52+
eyre = { version = "0.6.1", optional = true }
53+
stable-eyre = { version = "0.2.1", optional = true }
4754

4855
[dev-dependencies]
4956
http = "0.2.0"

src/error.rs

+27-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
//! HTTP error types
22
3+
use std::convert::TryInto;
34
use std::error::Error as StdError;
45
use std::fmt::{self, Debug, Display};
56

67
use crate::StatusCode;
7-
use std::convert::TryInto;
8+
9+
#[cfg(all(not(backtrace), feature = "error_eyre"))]
10+
use stable_eyre::BacktraceExt;
11+
12+
#[cfg(feature = "error_anyhow")]
13+
use anyhow::Error as BaseError;
14+
#[cfg(feature = "error_eyre")]
15+
use eyre::Report as BaseError;
816

917
/// A specialized `Result` type for HTTP operations.
1018
///
@@ -14,7 +22,7 @@ pub type Result<T> = std::result::Result<T, Error>;
1422

1523
/// The error type for HTTP operations.
1624
pub struct Error {
17-
error: anyhow::Error,
25+
error: BaseError,
1826
status: crate::StatusCode,
1927
type_name: Option<&'static str>,
2028
}
@@ -29,7 +37,7 @@ impl Error {
2937
where
3038
S: TryInto<StatusCode>,
3139
S::Error: Debug,
32-
E: Into<anyhow::Error>,
40+
E: Into<BaseError>,
3341
{
3442
Self {
3543
status: status
@@ -51,7 +59,7 @@ impl Error {
5159
status: status
5260
.try_into()
5361
.expect("Could not convert into a valid `StatusCode`"),
54-
error: anyhow::Error::msg(msg),
62+
error: BaseError::msg(msg),
5563
type_name: None,
5664
}
5765
}
@@ -96,7 +104,7 @@ impl Error {
96104
/// compiled on a toolchain that does not support backtraces, or
97105
/// if executed without backtraces enabled with
98106
/// `RUST_LIB_BACKTRACE=1`.
99-
#[cfg(backtrace)]
107+
#[cfg(all(backtrace, feature = "error_anyhow"))]
100108
pub fn backtrace(&self) -> Option<&std::backtrace::Backtrace> {
101109
let backtrace = self.error.backtrace();
102110
if let std::backtrace::BacktraceStatus::Captured = backtrace.status() {
@@ -106,12 +114,24 @@ impl Error {
106114
}
107115
}
108116

109-
#[cfg(not(backtrace))]
117+
#[cfg(all(not(backtrace), feature = "error_anyhow"))]
110118
#[allow(missing_docs)]
111119
pub fn backtrace(&self) -> Option<()> {
112120
None
113121
}
114122

123+
#[cfg(all(backtrace, feature = "error_eyre"))]
124+
#[allow(missing_docs)]
125+
pub fn backtrace(&self) -> Option<&std::backtrace::Backtrace> {
126+
self.error.backtrace()
127+
}
128+
129+
#[cfg(all(not(backtrace), feature = "error_eyre"))]
130+
#[allow(missing_docs)]
131+
pub fn backtrace(&self) -> Option<&backtrace::Backtrace> {
132+
self.error.backtrace()
133+
}
134+
115135
/// Attempt to downcast the error object to a concrete type.
116136
pub fn downcast<E>(self) -> std::result::Result<E, Self>
117137
where
@@ -158,7 +178,7 @@ impl Debug for Error {
158178
}
159179
}
160180

161-
impl<E: Into<anyhow::Error>> From<E> for Error {
181+
impl<E: Into<BaseError>> From<E> for Error {
162182
fn from(error: E) -> Self {
163183
Self::new(StatusCode::InternalServerError, error)
164184
}

tests/error.rs

+13
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,19 @@ fn option_ext() {
7171
assert_eq!(err.status(), StatusCode::NotFound);
7272
}
7373

74+
#[cfg(feature = "error_eyre")]
75+
#[test]
76+
fn eyre_error_into_http_types_error() {
77+
let eyre_error = eyre::Error::new(std::io::Error::new(std::io::ErrorKind::Other, "irrelevant"));
78+
let http_types_error: Error = eyre_error.into();
79+
assert_eq!(http_types_error.status(), StatusCode::InternalServerError);
80+
81+
let eyre_error = eyre::Error::new(std::io::Error::new(std::io::ErrorKind::Other, "irrelevant"));
82+
let http_types_error: Error = Error::new(StatusCode::ImATeapot, eyre_error);
83+
assert_eq!(http_types_error.status(), StatusCode::ImATeapot);
84+
}
85+
86+
#[cfg(feature = "error_anyhow")]
7487
#[test]
7588
fn anyhow_error_into_http_types_error() {
7689
let anyhow_error =

0 commit comments

Comments
 (0)