Remove error_on_non_2xx. (#272)
After the recent changes in #257, it's probably not necessary. It's now quite easy to use a match statement to extract responses for certain status codes, or all status codes. Add documentation on how to turn a status code error back into a Response.
This commit is contained in:
@@ -72,6 +72,12 @@ Ureq supports sending and receiving json, if you enable the "json" feature:
|
|||||||
.into_string()?;
|
.into_string()?;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Error handling
|
||||||
|
|
||||||
|
ureq returns errors via `Result<T, ureq::Error>`. That includes I/O errors,
|
||||||
|
protocol errors, and status code errors (when the server responded 4xx or
|
||||||
|
5xx). More details on the [Error] type.
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
To enable a minimal dependency tree, some features are off by default.
|
To enable a minimal dependency tree, some features are off by default.
|
||||||
@@ -192,6 +198,7 @@ If ureq is not what you're looking for, check out these other Rust HTTP clients:
|
|||||||
[post()]: https://docs.rs/ureq/latest/ureq/fn.post.html
|
[post()]: https://docs.rs/ureq/latest/ureq/fn.post.html
|
||||||
[put()]: https://docs.rs/ureq/latest/ureq/fn.put.html
|
[put()]: https://docs.rs/ureq/latest/ureq/fn.put.html
|
||||||
[Request]: https://docs.rs/ureq/latest/ureq/struct.Request.html
|
[Request]: https://docs.rs/ureq/latest/ureq/struct.Request.html
|
||||||
|
[Error]: https://docs.rs/ureq/latest/ureq/enum.Error.html
|
||||||
[Request::call()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.call
|
[Request::call()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.call
|
||||||
[Request::send()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.send
|
[Request::send()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.send
|
||||||
[Request::send_bytes()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.send_bytes
|
[Request::send_bytes()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.send_bytes
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
[post()]: https://docs.rs/ureq/latest/ureq/fn.post.html
|
[post()]: https://docs.rs/ureq/latest/ureq/fn.post.html
|
||||||
[put()]: https://docs.rs/ureq/latest/ureq/fn.put.html
|
[put()]: https://docs.rs/ureq/latest/ureq/fn.put.html
|
||||||
[Request]: https://docs.rs/ureq/latest/ureq/struct.Request.html
|
[Request]: https://docs.rs/ureq/latest/ureq/struct.Request.html
|
||||||
|
[Error]: https://docs.rs/ureq/latest/ureq/enum.Error.html
|
||||||
[Request::call()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.call
|
[Request::call()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.call
|
||||||
[Request::send()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.send
|
[Request::send()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.send
|
||||||
[Request::send_bytes()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.send_bytes
|
[Request::send_bytes()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.send_bytes
|
||||||
|
|||||||
@@ -417,13 +417,13 @@ impl AgentBuilder {
|
|||||||
/// let result = ureq::builder()
|
/// let result = ureq::builder()
|
||||||
/// .redirects(1)
|
/// .redirects(1)
|
||||||
/// .build()
|
/// .build()
|
||||||
|
/// # ;
|
||||||
|
/// # let result = ureq::agent()
|
||||||
/// .get("http://httpbin.org/status/301")
|
/// .get("http://httpbin.org/status/301")
|
||||||
/// .error_on_non_2xx(false)
|
|
||||||
/// .call()?;
|
/// .call()?;
|
||||||
/// assert_ne!(result.status(), 301);
|
/// assert_ne!(result.status(), 301);
|
||||||
///
|
///
|
||||||
/// let result = ureq::post("http://httpbin.org/status/307")
|
/// let result = ureq::post("http://httpbin.org/status/307")
|
||||||
/// .error_on_non_2xx(false)
|
|
||||||
/// .send_bytes(b"some data")?;
|
/// .send_bytes(b"some data")?;
|
||||||
/// assert_eq!(result.status(), 307);
|
/// assert_eq!(result.status(), 307);
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
|
|||||||
17
src/error.rs
17
src/error.rs
@@ -42,6 +42,23 @@ use crate::Response;
|
|||||||
/// ureq::get(url).call()
|
/// ureq::get(url).call()
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// If you'd like to treat all status code errors as normal, successful responses,
|
||||||
|
/// you can use [Result::or_else](std::result::Result::or_else) like this:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use ureq::Error::Status;
|
||||||
|
/// # fn main() -> std::result::Result<(), ureq::Error> {
|
||||||
|
/// # ureq::is_test(true);
|
||||||
|
/// let resp = ureq::get("http://example.com/")
|
||||||
|
/// .call()
|
||||||
|
/// .or_else(|e| match e {
|
||||||
|
/// Status(_, r) => Ok(r), // turn status errors into Ok Responses.
|
||||||
|
/// _ => Err(e),
|
||||||
|
/// })?;
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// A response was successfully received but had status code >= 400.
|
/// A response was successfully received but had status code >= 400.
|
||||||
|
|||||||
@@ -82,6 +82,12 @@
|
|||||||
//! # fn main() {}
|
//! # fn main() {}
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
|
//! ## Error handling
|
||||||
|
//!
|
||||||
|
//! ureq returns errors via `Result<T, ureq::Error>`. That includes I/O errors,
|
||||||
|
//! protocol errors, and status code errors (when the server responded 4xx or
|
||||||
|
//! 5xx). More details on the [Error] type.
|
||||||
|
//!
|
||||||
//! ## Features
|
//! ## Features
|
||||||
//!
|
//!
|
||||||
//! To enable a minimal dependency tree, some features are off by default.
|
//! To enable a minimal dependency tree, some features are off by default.
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ impl Request {
|
|||||||
let unit = Unit::new(&self.agent, &self.method, &url, &self.headers, &reader);
|
let unit = Unit::new(&self.agent, &self.method, &url, &self.headers, &reader);
|
||||||
let response = unit::connect(unit, true, reader, None).map_err(|e| e.url(url.clone()))?;
|
let response = unit::connect(unit, true, reader, None).map_err(|e| e.url(url.clone()))?;
|
||||||
|
|
||||||
if self.error_on_non_2xx && response.status() >= 400 {
|
if response.status() >= 400 {
|
||||||
Err(Error::Status(response.status(), response))
|
Err(Error::Status(response.status(), response))
|
||||||
} else {
|
} else {
|
||||||
Ok(response)
|
Ok(response)
|
||||||
@@ -336,26 +336,6 @@ impl Request {
|
|||||||
.push((param.to_string(), value.to_string()));
|
.push((param.to_string(), value.to_string()));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// By default, if a response's status is anything but a 2xx or 3xx,
|
|
||||||
/// call()/send() and related methods will return an Error. If you want
|
|
||||||
/// to handle such responses as non-errors, set this to `false`.
|
|
||||||
///
|
|
||||||
/// Example:
|
|
||||||
/// ```
|
|
||||||
/// # fn main() -> Result<(), ureq::Error> {
|
|
||||||
/// # ureq::is_test(true);
|
|
||||||
/// let response = ureq::get("http://httpbin.org/status/500")
|
|
||||||
/// .error_on_non_2xx(false)
|
|
||||||
/// .call()?;
|
|
||||||
/// assert_eq!(response.status(), 500);
|
|
||||||
/// # Ok(())
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
pub fn error_on_non_2xx(mut self, value: bool) -> Self {
|
|
||||||
self.error_on_non_2xx = value;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ pub(crate) fn test_agent() -> Agent {
|
|||||||
let headers = read_request(&stream);
|
let headers = read_request(&stream);
|
||||||
if headers.0.is_empty() {
|
if headers.0.is_empty() {
|
||||||
// no headers probably means it's the initial request to check test server is up.
|
// no headers probably means it's the initial request to check test server is up.
|
||||||
|
} else if headers.path() == "/status/200" {
|
||||||
|
stream.write_all(b"HTTP/1.1 200 OK\r\n\r\n")?;
|
||||||
} else if headers.path() == "/status/500" {
|
} else if headers.path() == "/status/500" {
|
||||||
stream.write_all(b"HTTP/1.1 500 Server Internal Error\r\n\r\n")?;
|
stream.write_all(b"HTTP/1.1 500 Server Internal Error\r\n\r\n")?;
|
||||||
} else if headers.path() == "/bytes/100" {
|
} else if headers.path() == "/bytes/100" {
|
||||||
@@ -30,11 +32,11 @@ pub(crate) fn test_agent() -> Agent {
|
|||||||
stream.write_all(br#"{"hello": "world"}"#)?;
|
stream.write_all(br#"{"hello": "world"}"#)?;
|
||||||
} else if headers.path() == "/status/301" {
|
} else if headers.path() == "/status/301" {
|
||||||
stream.write_all(b"HTTP/1.1 301 Found\r\n")?;
|
stream.write_all(b"HTTP/1.1 301 Found\r\n")?;
|
||||||
stream.write_all(b"Location: /redirect/3\r\n")?;
|
stream.write_all(b"Location: /status/200\r\n")?;
|
||||||
stream.write_all(b"\r\n")?;
|
stream.write_all(b"\r\n")?;
|
||||||
} else if headers.path() == "/status/307" {
|
} else if headers.path() == "/status/307" {
|
||||||
stream.write_all(b"HTTP/1.1 307 Found\r\n")?;
|
stream.write_all(b"HTTP/1.1 307 Found\r\n")?;
|
||||||
stream.write_all(b"Location: /redirect/3\r\n")?;
|
stream.write_all(b"Location: /status/200\r\n")?;
|
||||||
stream.write_all(b"\r\n")?;
|
stream.write_all(b"\r\n")?;
|
||||||
} else {
|
} else {
|
||||||
stream.write_all(b"HTTP/1.1 200 OK\r\n")?;
|
stream.write_all(b"HTTP/1.1 200 OK\r\n")?;
|
||||||
|
|||||||
Reference in New Issue
Block a user