Skip to content

Commit c45e0f7

Browse files
committed
chore: custom Error with http status code support
1 parent 51119d3 commit c45e0f7

File tree

2 files changed

+71
-4
lines changed

2 files changed

+71
-4
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ keywords = [
2525
[dependencies]
2626
hyper = { version = "0.14", default-features = false, features = ["server", "tcp"] }
2727
anyhow = "1.0"
28+
thiserror = "1.0"
2829

2930
[dev-dependencies]
3031
hyper = { version = "0.14", features = ["tcp", "server", "http1"] }

src/error.rs

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,76 @@
1-
/// Just a `anyhow::Result` type alias.
2-
pub type Result<T = (), E = anyhow::Error> = anyhow::Result<T, E>;
1+
use hyper::StatusCode;
2+
use std::fmt;
3+
use thiserror::Error as BaseError;
34

4-
/// Just an `anyhow::Error` type alias.
5-
pub type Error = anyhow::Error;
5+
/// Just a `anyhow::Result` type alias.
6+
pub type Result<T = (), E = Error> = anyhow::Result<T, E>;
67

78
/// Just re-export some `anyhow` stuff.
89
pub use anyhow::anyhow;
910
pub use anyhow::bail;
1011
pub use anyhow::Context;
12+
13+
/// Custom `Error` with HTTP status code support.
14+
#[derive(BaseError, Debug)]
15+
pub struct Error {
16+
#[source]
17+
source: anyhow::Error,
18+
status: Option<StatusCode>,
19+
}
20+
21+
impl fmt::Display for Error {
22+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23+
fmt::Display::fmt(&self.source, f)
24+
}
25+
}
26+
27+
impl Error {
28+
/// Construct an ad-hoc an HTTP `Error` from another error type.
29+
pub fn from_err(error: anyhow::Error, status: Option<StatusCode>) -> Self {
30+
Self {
31+
source: error,
32+
status,
33+
}
34+
}
35+
36+
/// Construct an ad-hoc an HTTP `Error` from a string error.
37+
pub fn from_str(error: &str, status: Option<StatusCode>) -> Self {
38+
Self {
39+
source: anyhow::anyhow!(error.to_owned()),
40+
status,
41+
}
42+
}
43+
44+
/// Gets a reference to the `Error` source.
45+
pub fn source(&self) -> &anyhow::Error {
46+
&self.source
47+
}
48+
49+
/// Gets the HTTP status code associated with the error.
50+
pub fn status(&self) -> Option<StatusCode> {
51+
self.status
52+
}
53+
54+
/// Sets the HTTP status code associated with the error.
55+
pub fn status_mut(&mut self) -> &mut Option<StatusCode> {
56+
&mut self.status
57+
}
58+
}
59+
60+
impl From<anyhow::Error> for Error {
61+
/// Converts whatever error into an HTTP `Error`.
62+
fn from(error: anyhow::Error) -> Self {
63+
Self {
64+
source: error,
65+
status: None,
66+
}
67+
}
68+
}
69+
70+
/// Construct an ad-hoc `Error` from a string or existing non-anyhow error value.
71+
#[macro_export]
72+
macro_rules! error {
73+
($($arg:tt)*) => {{
74+
Error::from(anyhow::anyhow!($($arg)*))
75+
}}
76+
}

0 commit comments

Comments
 (0)