Skip to content

Commit 08937a1

Browse files
committed
Add error::ResultDynErrExt
1 parent 4a53890 commit 08937a1

File tree

1 file changed

+41
-9
lines changed

1 file changed

+41
-9
lines changed

src/error.rs

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,18 @@ impl From<StatusCode> for Error {
5656
}
5757
}
5858

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

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

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

92-
impl<T, E: std::error::Error + Send + Sync + 'static> ResultExt<T> for std::result::Result<T, E> {
124+
impl<T> ResultDynErrExt<T> for std::result::Result<T, Box<dyn std::error::Error + Send + Sync>> {
93125
fn with_err_status<S>(self, status: S) -> EndpointResult<T>
94126
where
95127
StatusCode: HttpTryFrom<S>,
96128
{
97129
self.map_err(|e| Error {
98130
resp: Response::builder()
99131
.status(status)
100-
.extension(Cause(Box::new(e)))
132+
.extension(Cause(e))
101133
.body(Body::empty())
102134
.unwrap(),
103135
})

0 commit comments

Comments
 (0)