1
- // use core::pin::Pin;
2
- // use futures::future::Future;
3
1
use http:: { HttpTryFrom , Response , StatusCode } ;
4
2
use http_service:: Body ;
5
3
@@ -55,6 +53,18 @@ impl From<StatusCode> for Error {
55
53
}
56
54
}
57
55
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
+
58
68
/// Extends the `Result` type with convenient methods for constructing Tide errors.
59
69
pub trait ResultExt < T > : Sized {
60
70
/// Convert to an `EndpointResult`, treating the `Err` case as a client
@@ -76,27 +86,47 @@ pub trait ResultExt<T>: Sized {
76
86
StatusCode : HttpTryFrom < S > ;
77
87
}
78
88
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
+ }
83
97
}
84
98
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 )
88
106
}
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 > ;
89
119
}
90
120
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 > > {
92
122
fn with_err_status < S > ( self , status : S ) -> EndpointResult < T >
93
123
where
94
124
StatusCode : HttpTryFrom < S > ,
95
125
{
96
126
self . map_err ( |e| Error {
97
127
resp : Response :: builder ( )
98
128
. status ( status)
99
- . extension ( Cause ( Box :: new ( e ) ) )
129
+ . extension ( Cause ( e ) )
100
130
. body ( Body :: empty ( ) )
101
131
. unwrap ( ) ,
102
132
} )
0 commit comments