Skip to content

Commit

Permalink
Remove curl error types from API
Browse files Browse the repository at this point in the history
  • Loading branch information
sagebind committed Dec 24, 2020
1 parent 9b713ef commit cb5b36c
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 86 deletions.
26 changes: 17 additions & 9 deletions src/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,22 @@ impl AgentBuilder {
let mut multi = curl::multi::Multi::new();

if max_connections > 0 {
multi.set_max_total_connections(max_connections)?;
multi
.set_max_total_connections(max_connections)
.map_err(Error::from_any)?;
}

if max_connections_per_host > 0 {
multi.set_max_host_connections(max_connections_per_host)?;
multi
.set_max_host_connections(max_connections_per_host)
.map_err(Error::from_any)?;
}

// Only set maxconnects if greater than 0, because 0 actually means unlimited.
if connection_cache_size > 0 {
multi.set_max_connects(connection_cache_size)?;
multi
.set_max_connects(connection_cache_size)
.map_err(Error::from_any)?;
}

let agent = AgentContext {
Expand Down Expand Up @@ -318,8 +324,8 @@ impl AgentContext {
);

// Register the request with curl.
let mut handle = self.multi.add2(request)?;
handle.set_token(id)?;
let mut handle = self.multi.add2(request).map_err(Error::from_any)?;
handle.set_token(id).map_err(Error::from_any)?;

// Add the handle to our bookkeeping structure.
entry.insert(handle);
Expand All @@ -334,9 +340,9 @@ impl AgentContext {
result: Result<(), curl::Error>,
) -> Result<(), Error> {
let handle = self.requests.remove(token);
let mut handle = self.multi.remove2(handle)?;
let mut handle = self.multi.remove2(handle).map_err(Error::from_any)?;

handle.get_mut().set_result(result.map_err(Error::from));
handle.get_mut().set_result(result.map_err(Error::from_any));

Ok(())
}
Expand Down Expand Up @@ -445,7 +451,7 @@ impl AgentContext {

#[tracing::instrument(level = "trace", skip(self))]
fn dispatch(&mut self) -> Result<(), Error> {
self.multi.perform()?;
self.multi.perform().map_err(Error::from_any)?;

// Collect messages from curl about requests that have completed,
// whether successfully or with an error.
Expand Down Expand Up @@ -488,7 +494,9 @@ impl AgentContext {
self.dispatch()?;

// Block until activity is detected or the timeout passes.
self.multi.wait(&mut wait_fds, WAIT_TIMEOUT)?;
self.multi
.wait(&mut wait_fds, WAIT_TIMEOUT)
.map_err(Error::from_any)?;

// We might have woken up early from the notify fd, so drain the
// socket to clear it.
Expand Down
4 changes: 2 additions & 2 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,7 @@ impl HttpClient {
curl::easy::Easy2<RequestHandler>,
impl Future<Output = Result<Response<ResponseBodyReader>, Error>>,
),
Error,
curl::Error,
> {
// Prepare the request plumbing.
// let (mut parts, body) = request.into_parts();
Expand Down Expand Up @@ -1202,7 +1202,7 @@ impl crate::interceptor::Invoke for &HttpClient {
.unwrap_or(false);

// Create and configure a curl easy handle to fulfil the request.
let (easy, future) = self.create_easy_handle(request)?;
let (easy, future) = self.create_easy_handle(request).map_err(Error::from_any)?;

// Send the request to the agent to be executed.
self.inner.agent.submit_request(easy)?;
Expand Down
142 changes: 69 additions & 73 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,82 @@ impl Error {

/// Statically cast a given error into an Isahc error, converting if
/// necessary.
///
/// This is useful for converting or creating errors from external types
/// without publicly implementing `From` over them and leaking them into our
/// API.
pub(crate) fn from_any<E>(error: E) -> Self
where
E: StdError + Send + Sync + 'static,
{
match_type! {
<error as Error> => error,
<error as std::io::Error> => error.into(),
<error as curl::Error> => {
Self::with_context(
if error.is_ssl_certproblem() || error.is_ssl_cacert_badfile() {
ErrorKind::BadClientCertificate
} else if error.is_peer_failed_verification()
|| error.is_ssl_cacert()
|| error.is_ssl_cipher()
|| error.is_ssl_issuer_error()
{
ErrorKind::BadServerCertificate
} else if error.is_interface_failed() {
ErrorKind::ClientInitialization
} else if error.is_couldnt_connect() || error.is_ssl_connect_error() {
ErrorKind::ConnectionFailed
} else if error.is_bad_content_encoding() || error.is_conv_failed() {
ErrorKind::InvalidContentEncoding
} else if error.is_login_denied() {
ErrorKind::InvalidCredentials
} else if error.is_url_malformed() {
ErrorKind::InvalidRequest
} else if error.is_couldnt_resolve_host() || error.is_couldnt_resolve_proxy() {
ErrorKind::NameResolution
} else if error.is_got_nothing()
|| error.is_http2_error()
|| error.is_http2_stream_error()
|| error.is_unsupported_protocol()
|| error.code() == curl_sys::CURLE_FTP_WEIRD_SERVER_REPLY
{
ErrorKind::ProtocolViolation
} else if error.is_send_error()
|| error.is_recv_error()
|| error.is_read_error()
|| error.is_write_error()
|| error.is_upload_failed()
|| error.is_send_fail_rewind()
|| error.is_aborted_by_callback()
|| error.is_partial_file()
{
ErrorKind::Io
} else if error.is_ssl_engine_initfailed()
|| error.is_ssl_engine_notfound()
|| error.is_ssl_engine_setfailed()
{
ErrorKind::TlsEngine
} else if error.is_operation_timedout() {
ErrorKind::Timeout
} else if error.is_too_many_redirects() {
ErrorKind::TooManyRedirects
} else {
ErrorKind::Unknown
},
error.extra_description().map(String::from),
error,
)
},
<error as curl::MultiError> => {
Self::new(
if error.is_bad_socket() {
ErrorKind::Io
} else {
ErrorKind::Unknown
},
error,
)
},
error => Error::new(ErrorKind::Unknown, error),
}
}
Expand Down Expand Up @@ -333,79 +402,6 @@ impl From<http::Error> for Error {
}
}

#[doc(hidden)]
impl From<curl::Error> for Error {
fn from(error: curl::Error) -> Error {
Self::with_context(
if error.is_ssl_certproblem() || error.is_ssl_cacert_badfile() {
ErrorKind::BadClientCertificate
} else if error.is_peer_failed_verification()
|| error.is_ssl_cacert()
|| error.is_ssl_cipher()
|| error.is_ssl_issuer_error()
{
ErrorKind::BadServerCertificate
} else if error.is_interface_failed() {
ErrorKind::ClientInitialization
} else if error.is_couldnt_connect() || error.is_ssl_connect_error() {
ErrorKind::ConnectionFailed
} else if error.is_bad_content_encoding() || error.is_conv_failed() {
ErrorKind::InvalidContentEncoding
} else if error.is_login_denied() {
ErrorKind::InvalidCredentials
} else if error.is_url_malformed() {
ErrorKind::InvalidRequest
} else if error.is_couldnt_resolve_host() || error.is_couldnt_resolve_proxy() {
ErrorKind::NameResolution
} else if error.is_got_nothing()
|| error.is_http2_error()
|| error.is_http2_stream_error()
|| error.is_unsupported_protocol()
|| error.code() == curl_sys::CURLE_FTP_WEIRD_SERVER_REPLY
{
ErrorKind::ProtocolViolation
} else if error.is_send_error()
|| error.is_recv_error()
|| error.is_read_error()
|| error.is_write_error()
|| error.is_upload_failed()
|| error.is_send_fail_rewind()
|| error.is_aborted_by_callback()
|| error.is_partial_file()
{
ErrorKind::Io
} else if error.is_ssl_engine_initfailed()
|| error.is_ssl_engine_notfound()
|| error.is_ssl_engine_setfailed()
{
ErrorKind::TlsEngine
} else if error.is_operation_timedout() {
ErrorKind::Timeout
} else if error.is_too_many_redirects() {
ErrorKind::TooManyRedirects
} else {
ErrorKind::Unknown
},
error.extra_description().map(String::from),
error,
)
}
}

#[doc(hidden)]
impl From<curl::MultiError> for Error {
fn from(error: curl::MultiError) -> Error {
Self::new(
if error.is_bad_socket() {
ErrorKind::Io
} else {
ErrorKind::Unknown
},
error,
)
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 2 additions & 2 deletions src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ mod tests {
fn utf8_decode() {
let mut decoder = Decoder::new(encoding_rs::UTF_8);

assert_eq!(decoder.push(b"hello"), &[]);
assert_eq!(decoder.push(b" "), &[]);
assert_eq!(decoder.push(b"hello"), b"");
assert_eq!(decoder.push(b" "), b"");
assert_eq!(decoder.finish(b"world"), "hello world");
}

Expand Down

0 comments on commit cb5b36c

Please sign in to comment.