Switch to Result-based API. (#132)

Gets rid of synthetic_error, and makes the various send_* methods return `Result<Response, Error>`.
Introduces a new error type "HTTP", which represents an error due to status codes 4xx or 5xx.
The HTTP error type contains a boxed Response, so users can read the actual response if they want.
Adds an `error_for_status` setting to disable the functionality of treating 4xx and 5xx as errors.
Adds .unwrap() to a lot of tests.

Fixes #128.
This commit is contained in:
Jacob Hoffman-Andrews
2020-10-17 00:40:48 -07:00
committed by GitHub
parent 257d4e54dd
commit e36c1c2aa1
19 changed files with 222 additions and 344 deletions

View File

@@ -24,13 +24,11 @@
//! "rust": true
//! }));
//!
//! // .ok() tells if response is 200-299.
//! if resp.ok() {
//! if let Ok(resp) = resp {
//! println!("success: {}", resp.into_string()?);
//! } else {
//! // This can include errors like failure to parse URL or connect timeout.
//! // They are treated as synthetic HTTP-level error statuses.
//! println!("error {}: {}", resp.status(), resp.into_string()?);
//! println!("error {}", resp.err().unwrap());
//! }
//! Ok(())
//! }
@@ -103,20 +101,6 @@
//! we first check if the user has set a `; charset=<whatwg charset>` and attempt
//! to encode the request body using that.
//!
//! # Synthetic errors
//!
//! Rather than exposing a custom error type through results, this library has opted for
//! representing potential connection/TLS/etc errors as HTTP response codes. These invented codes
//! are called "[synthetic](struct.Response.html#method.synthetic)."
//!
//! The idea is that from a library user's point of view the distinction of whether a failure
//! originated in the remote server (500, 502) etc, or some transient network failure, the code
//! path of handling that would most often be the same.
//!
//! As a result, reading from a Response may yield an error message generated by the ureq library.
//! To handle these errors, use the
//! [`response.synthetic_error()`](struct.Response.html#method.synthetic_error) method.
//!
mod agent;
mod body;
@@ -158,7 +142,7 @@ pub fn agent() -> Agent {
/// Make a request setting the HTTP method via a string.
///
/// ```
/// ureq::request("GET", "https://www.google.com").call();
/// ureq::request("GET", "http://example.com").call().unwrap();
/// ```
pub fn request(method: &str, path: &str) -> Request {
Agent::new().request(method, path)
@@ -210,7 +194,7 @@ mod tests {
#[test]
fn connect_http_google() {
let resp = get("http://www.google.com/").call();
let resp = get("http://www.google.com/").call().unwrap();
assert_eq!(
"text/html; charset=ISO-8859-1",
resp.header("content-type").unwrap()
@@ -221,7 +205,7 @@ mod tests {
#[test]
#[cfg(any(feature = "tls", feature = "native-tls"))]
fn connect_https_google() {
let resp = get("https://www.google.com/").call();
let resp = get("https://www.google.com/").call().unwrap();
assert_eq!(
"text/html; charset=ISO-8859-1",
resp.header("content-type").unwrap()
@@ -232,8 +216,7 @@ mod tests {
#[test]
#[cfg(any(feature = "tls", feature = "native-tls"))]
fn connect_https_invalid_name() {
let resp = get("https://example.com{REQUEST_URI}/").call();
assert_eq!(400, resp.status());
assert!(resp.synthetic());
let result = get("https://example.com{REQUEST_URI}/").call();
assert!(matches!(result.unwrap_err(), Error::DnsFailed(_)));
}
}