Skip to content

Commit 2878aba

Browse files
updogliuyoshuawuyts
authored andcommitted
Add ResultDynErrExt (#216)
1 parent 85b85e9 commit 2878aba

File tree

1 file changed

+41
-11
lines changed

1 file changed

+41
-11
lines changed

tide-core/src/error.rs

+41-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// use core::pin::Pin;
2-
// use futures::future::Future;
31
use http::{HttpTryFrom, Response, StatusCode};
42
use http_service::Body;
53

@@ -55,6 +53,18 @@ impl From<StatusCode> for Error {
5553
}
5654
}
5755

56+
/// Extends the `Response` type with a method to extract error causes when applicable.
57+
pub trait ResponseExt {
58+
/// Extract the cause of the unsuccessful response, if any
59+
fn err_cause(&self) -> Option<&(dyn std::error::Error + Send + Sync + 'static)>;
60+
}
61+
62+
impl<T> ResponseExt for Response<T> {
63+
fn err_cause(&self) -> Option<&(dyn std::error::Error + Send + Sync + 'static)> {
64+
self.extensions().get().map(|Cause(c)| &**c)
65+
}
66+
}
67+
5868
/// Extends the `Result` type with convenient methods for constructing Tide errors.
5969
pub trait ResultExt<T>: Sized {
6070
/// Convert to an `EndpointResult`, treating the `Err` case as a client
@@ -76,27 +86,47 @@ pub trait ResultExt<T>: Sized {
7686
StatusCode: HttpTryFrom<S>;
7787
}
7888

79-
/// Extends the `Response` type with a method to extract error causes when applicable.
80-
pub trait ResponseExt {
81-
/// Extract the cause of the unsuccessful response, if any
82-
fn err_cause(&self) -> Option<&(dyn std::error::Error + Send + Sync + 'static)>;
89+
impl<T, E: std::error::Error + Send + Sync + 'static> ResultExt<T> for std::result::Result<T, E> {
90+
fn with_err_status<S>(self, status: S) -> EndpointResult<T>
91+
where
92+
StatusCode: HttpTryFrom<S>,
93+
{
94+
let r = self.map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>);
95+
r.with_err_status(status)
96+
}
8397
}
8498

85-
impl<T> ResponseExt for Response<T> {
86-
fn err_cause(&self) -> Option<&(dyn std::error::Error + Send + Sync + 'static)> {
87-
self.extensions().get().map(|Cause(c)| &**c)
99+
/// Extends the `Result` type using `std::error::Error` trait object as the error type with
100+
/// convenient methods for constructing Tide errors.
101+
pub trait ResultDynErrExt<T>: Sized {
102+
/// Convert to an `EndpointResult`, treating the `Err` case as a client
103+
/// error (response code 400).
104+
fn client_err(self) -> EndpointResult<T> {
105+
self.with_err_status(400)
88106
}
107+
108+
/// Convert to an `EndpointResult`, treating the `Err` case as a server
109+
/// error (response code 500).
110+
fn server_err(self) -> EndpointResult<T> {
111+
self.with_err_status(500)
112+
}
113+
114+
/// Convert to an `EndpointResult`, wrapping the `Err` case with a custom
115+
/// response status.
116+
fn with_err_status<S>(self, status: S) -> EndpointResult<T>
117+
where
118+
StatusCode: HttpTryFrom<S>;
89119
}
90120

91-
impl<T, E: std::error::Error + Send + Sync + 'static> ResultExt<T> for std::result::Result<T, E> {
121+
impl<T> ResultDynErrExt<T> for std::result::Result<T, Box<dyn std::error::Error + Send + Sync>> {
92122
fn with_err_status<S>(self, status: S) -> EndpointResult<T>
93123
where
94124
StatusCode: HttpTryFrom<S>,
95125
{
96126
self.map_err(|e| Error {
97127
resp: Response::builder()
98128
.status(status)
99-
.extension(Cause(Box::new(e)))
129+
.extension(Cause(e))
100130
.body(Body::empty())
101131
.unwrap(),
102132
})

0 commit comments

Comments
 (0)