Add error_for_status.
This makes it it easy to turn error responses into error results.
This commit is contained in:
		
				
					committed by
					
						 Sean McArthur
						Sean McArthur
					
				
			
			
				
	
			
			
			
						parent
						
							a25b9a6002
						
					
				
				
					commit
					855e6615eb
				
			| @@ -59,6 +59,40 @@ impl Response { | ||||
|             _marker: PhantomData, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Turn a response into an error if the server returned an error. | ||||
|     // XXX: example disabled since rustdoc still tries to run it | ||||
|     // when the 'unstable' feature isn't active, making the import | ||||
|     // fail. | ||||
|     // | ||||
|     // # Example | ||||
|     // | ||||
|     // ``` | ||||
|     // # use reqwest::unstable::async::Response; | ||||
|     // fn on_response(res: Response) { | ||||
|     //     match res.error_for_status() { | ||||
|     //         Ok(_res) => (), | ||||
|     //         Err(err) => { | ||||
|     //             // asserting a 400 as an example | ||||
|     //             // it could be any status between 400...599 | ||||
|     //             assert_eq!( | ||||
|     //                 err.status(), | ||||
|     //                 Some(reqwest::StatusCode::BadRequest) | ||||
|     //             ); | ||||
|     //         } | ||||
|     //     } | ||||
|     // } | ||||
|     // ``` | ||||
|     #[inline] | ||||
|     pub fn error_for_status(self) -> ::Result<Self> { | ||||
|         if self.status.is_client_error() { | ||||
|             Err(::error::client_error(self.url, self.status)) | ||||
|         } else if self.status.is_server_error() { | ||||
|             Err(::error::server_error(self.url, self.status)) | ||||
|         } else { | ||||
|             Ok(self) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										67
									
								
								src/error.rs
									
									
									
									
									
								
							
							
						
						
									
										67
									
								
								src/error.rs
									
									
									
									
									
								
							| @@ -2,7 +2,7 @@ use std::error::Error as StdError; | ||||
| use std::fmt; | ||||
| use std::io; | ||||
|  | ||||
| use Url; | ||||
| use {StatusCode, Url}; | ||||
|  | ||||
| /// The Errors that may occur when processing a `Request`. | ||||
| /// | ||||
| @@ -118,7 +118,9 @@ impl Error { | ||||
|             Kind::UrlEncoded(ref e) => Some(e), | ||||
|             Kind::Json(ref e) => Some(e), | ||||
|             Kind::TooManyRedirects | | ||||
|             Kind::RedirectLoop => None, | ||||
|             Kind::RedirectLoop | | ||||
|             Kind::ClientError(_) | | ||||
|             Kind::ServerError(_) => None, | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -150,6 +152,34 @@ impl Error { | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Returns true if the error is from a request returning a 4xx error. | ||||
|     #[inline] | ||||
|     pub fn is_client_error(&self) -> bool { | ||||
|         match self.kind { | ||||
|             Kind::ClientError(_) => true, | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Returns true if the error is from a request returning a 5xx error. | ||||
|     #[inline] | ||||
|     pub fn is_server_error(&self) -> bool { | ||||
|         match self.kind { | ||||
|             Kind::ServerError(_) => true, | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Returns the status code, if the error was generated from a response. | ||||
|     #[inline] | ||||
|     pub fn status(&self) -> Option<StatusCode> { | ||||
|         match self.kind { | ||||
|             Kind::ClientError(code) | | ||||
|             Kind::ServerError(code) => Some(code), | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl fmt::Display for Error { | ||||
| @@ -167,6 +197,14 @@ impl fmt::Display for Error { | ||||
|             Kind::Json(ref e) => fmt::Display::fmt(e, f), | ||||
|             Kind::TooManyRedirects => f.write_str("Too many redirects"), | ||||
|             Kind::RedirectLoop => f.write_str("Infinite redirect loop"), | ||||
|             Kind::ClientError(ref code) => { | ||||
|                 f.write_str("Client Error: ")?; | ||||
|                 fmt::Display::fmt(code, f) | ||||
|             } | ||||
|             Kind::ServerError(ref code) => { | ||||
|                 f.write_str("Server Error: ")?; | ||||
|                 fmt::Display::fmt(code, f) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -182,6 +220,8 @@ impl StdError for Error { | ||||
|             Kind::Json(ref e) => e.description(), | ||||
|             Kind::TooManyRedirects => "Too many redirects", | ||||
|             Kind::RedirectLoop => "Infinite redirect loop", | ||||
|             Kind::ClientError(_) => "Client Error", | ||||
|             Kind::ServerError(_) => "Server Error", | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -194,7 +234,9 @@ impl StdError for Error { | ||||
|             Kind::UrlEncoded(ref e) => e.cause(), | ||||
|             Kind::Json(ref e) => e.cause(), | ||||
|             Kind::TooManyRedirects | | ||||
|             Kind::RedirectLoop => None, | ||||
|             Kind::RedirectLoop | | ||||
|             Kind::ClientError(_) | | ||||
|             Kind::ServerError(_) => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -211,6 +253,8 @@ pub enum Kind { | ||||
|     Json(::serde_json::Error), | ||||
|     TooManyRedirects, | ||||
|     RedirectLoop, | ||||
|     ClientError(StatusCode), | ||||
|     ServerError(StatusCode), | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -374,6 +418,22 @@ pub fn timedout(url: Option<Url>) -> Error { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[inline] | ||||
| pub fn client_error(url: Url, status: StatusCode) -> Error { | ||||
|     Error { | ||||
|         kind: Kind::ClientError(status), | ||||
|         url: Some(url), | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[inline] | ||||
| pub fn server_error(url: Url, status: StatusCode) -> Error { | ||||
|     Error { | ||||
|         kind: Kind::ServerError(status), | ||||
|         url: Some(url), | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
| @@ -438,7 +498,6 @@ mod tests { | ||||
|         let link = Chain(Some(root)); | ||||
|         let io = ::std::io::Error::new(::std::io::ErrorKind::Other, link); | ||||
|         let err = Error { kind: Kind::Io(io), url: None }; | ||||
|  | ||||
|         assert!(err.cause().is_some()); | ||||
|         assert_eq!(err.to_string(), "chain: root"); | ||||
|     } | ||||
|   | ||||
| @@ -156,6 +156,34 @@ impl Response { | ||||
|         // Went for easier for now, just to get it working. | ||||
|         serde_json::from_reader(self).map_err(::error::from) | ||||
|     } | ||||
|  | ||||
|     /// Turn a response into an error if the server returned an error. | ||||
|     /// | ||||
|     /// # Example | ||||
|     /// | ||||
|     /// ```rust,no_run | ||||
|     /// # extern crate reqwest; | ||||
|     /// # fn run() -> Result<(), Box<::std::error::Error>> { | ||||
|     /// let res = reqwest::get("http://httpbin.org/status/400")? | ||||
|     ///     .error_for_status(); | ||||
|     /// if let Err(err) = res { | ||||
|     ///     assert_eq!(err.status(), Some(reqwest::StatusCode::BadRequest)); | ||||
|     /// } | ||||
|     /// # Ok(()) | ||||
|     /// # } | ||||
|     /// # fn main() {} | ||||
|     /// ``` | ||||
|     #[inline] | ||||
|     pub fn error_for_status(self) -> ::Result<Self> { | ||||
|         let Response { body, inner, _thread_handle } = self; | ||||
|         inner.error_for_status().map(move |inner| { | ||||
|             Response { | ||||
|                 body: body, | ||||
|                 inner: inner, | ||||
|                 _thread_handle: _thread_handle, | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Read for Response { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user