Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

redirect and error reform #88

Merged
merged 1 commit into from
May 9, 2017
Merged

redirect and error reform #88

merged 1 commit into from
May 9, 2017

Conversation

seanmonstar
Copy link
Owner

  • Error has been made an opaque struct.
  • RedirectPolicy now makes use of RedirectAttempt and RedirectAction.

- `Error` has been made an opaque struct.
- `RedirectPolicy` now makes use of `RedirectAttempt` and `RedirectAction`.
@seanmonstar seanmonstar merged commit be1b1f0 into master May 9, 2017
@seanmonstar seanmonstar deleted the error-reform branch May 9, 2017 20:36
@Arnavion
Copy link

The problem with hiding the underlying error behind std::error::Error::cause() is that it's no longer possible to actually get to said underlying error and do something based on what kind of error it is.

With v0.5 I could have code that, say, retried the request on ConnectionAborted:

match send(url) {
    Err(::reqwest::Error::Http(::reqwest::HyperError::Io(ref io_err))) => match io_err.kind() {
        ::std::io::ErrorKind::ConnectionAborted => /* retry */,
        _ => /* abort */,
    },
}

but with v0.6 the result of reqwest_err.cause().unwrap() cannot be downcast to a concrete type.

Would it make sense to add as_http(&self) -> &::hyper::Error, as_serialization(&self) -> &::serde_urlencoded::ser::Error, etc methods to Error ?

@seanmonstar
Copy link
Owner Author

I believe the cause can be downcast. This doesn't work?

if let Some(cause) = err.cause() {
    match cause.downcast_ref::<hyper::Error>() {
        Some(hyper::Error::Io(ref io)) => assert_eq!(io.kind(), ErrorKind::ConnectionAborted),
        _ => ()
    }
}

The ::<hyper::Error> may not even be needed, since it could be inferred by the match, I think.

@Arnavion
Copy link

Arnavion commented May 11, 2017

std::error::Error::downcast_ref is similar to Any::downcast_ref and thus requires a 'static bound. It's a long-standing issue - rust-lang/rust#35943

@seanmonstar
Copy link
Owner Author

Oh what the...

@seanmonstar
Copy link
Owner Author

Ok, so there could be a few solutions to this:

  • Add an inherent (so not impl Trait for Error) fn cause(&self) -> Option<&Error + 'static>, so that downcasting can work.
  • Add some TryFrom impls to allow static downcasting. Not stable yet, but will be stable in 1.18.
  • Add as_http() -> Option<&hyper::Error> and friends, as suggested.
  • Add some sort of is_io_kind(&self, std::io::ErrorKind) -> bool method.
  • Something else?

@compressed
Copy link

I was bitten by this too in 0.6, as I have code that does retries on ConnectionAborted. The first option seems to be the most straight-forward and flexible, although it could be confusing having two versions of the cause fn. The is_io_kind is an interesting option, that would work for me, but I guess if others are matching on other Error variants it won't work for them.

@seanmonstar
Copy link
Owner Author

I'm still not certain what would be the best thing to expose.

Tangentially, would there be benefit in reqwest retrying the requests itself, when the method is idempotent?

@seanmonstar
Copy link
Owner Author

Oh, looking at std::io::Error, it has an inherent get_ref method that was added since cause wasn't usable. Perhaps reqwest::Error should get get_ref?

@Arnavion
Copy link

get_ref is a good idea.

@seanmonstar
Copy link
Owner Author

I just published v0.6.1 that adds Error::get_ref that allows downcasting.

@Arnavion
Copy link

Works like a charm. Thanks!

repi pushed a commit to EmbarkStudios/reqwest that referenced this pull request Dec 20, 2019
This issue is related to seanmonstar#88 and would prevent issues like it when
openssl 1.2 comes out.

This commit adds support for building reqwest with rustls support, using
the new feature flag `rustls`.

This fixes seanmonstar#136.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants