Skip to content

Commit 297dc4c

Browse files
authored
feat(client): include connection info in Client::send_request errors (#2749)
1 parent 00d52e4 commit 297dc4c

File tree

2 files changed

+37
-15
lines changed

2 files changed

+37
-15
lines changed

src/client/client.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ where
251251
if req.version() == Version::HTTP_2 {
252252
warn!("Connection is HTTP/1, but request requires HTTP/2");
253253
return Err(ClientError::Normal(
254-
crate::Error::new_user_unsupported_version(),
254+
crate::Error::new_user_unsupported_version().with_client_connect_info(pooled.conn_info.clone()),
255255
));
256256
}
257257

@@ -281,18 +281,20 @@ where
281281
authority_form(req.uri_mut());
282282
}
283283

284-
let fut = pooled
285-
.send_request_retryable(req)
286-
.map_err(ClientError::map_with_reused(pooled.is_reused()));
284+
let mut res = match pooled.send_request_retryable(req).await {
285+
Err((err, orig_req)) => {
286+
return Err(ClientError::map_with_reused(pooled.is_reused())((
287+
err.with_client_connect_info(pooled.conn_info.clone()),
288+
orig_req,
289+
)));
290+
}
291+
Ok(res) => res,
292+
};
287293

288294
// If the Connector included 'extra' info, add to Response...
289-
let extra_info = pooled.conn_info.extra.clone();
290-
let fut = fut.map_ok(move |mut res| {
291-
if let Some(extra) = extra_info {
292-
extra.set(res.extensions_mut());
293-
}
294-
res
295-
});
295+
if let Some(extra) = &pooled.conn_info.extra {
296+
extra.set(res.extensions_mut());
297+
}
296298

297299
// As of [email protected], there is a race condition in the mpsc
298300
// channel, such that sending when the receiver is closing can
@@ -302,11 +304,9 @@ where
302304
// To counteract this, we must check if our senders 'want' channel
303305
// has been closed after having tried to send. If so, error out...
304306
if pooled.is_closed() {
305-
return fut.await;
307+
return Ok(res);
306308
}
307309

308-
let mut res = fut.await?;
309-
310310
// If pooled is HTTP/2, we can toss this reference immediately.
311311
//
312312
// when pooled is dropped, it will try to insert back into the

src/error.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
//! Error and Result module.
2+
3+
#[cfg(all(feature = "client", any(feature = "http1", feature = "http2")))]
4+
use crate::client::connect::Connected;
25
use std::error::Error as StdError;
36
use std::fmt;
47

@@ -15,6 +18,8 @@ pub struct Error {
1518
struct ErrorImpl {
1619
kind: Kind,
1720
cause: Option<Cause>,
21+
#[cfg(all(feature = "client", any(feature = "http1", feature = "http2")))]
22+
connect_info: Option<Connected>,
1823
}
1924

2025
#[derive(Debug)]
@@ -210,9 +215,20 @@ impl Error {
210215
self.inner.cause
211216
}
212217

218+
/// Returns the info of the client connection on which this error occurred.
219+
#[cfg(all(feature = "client", any(feature = "http1", feature = "http2")))]
220+
pub fn client_connect_info(&self) -> Option<&Connected> {
221+
self.inner.connect_info.as_ref()
222+
}
223+
213224
pub(super) fn new(kind: Kind) -> Error {
214225
Error {
215-
inner: Box::new(ErrorImpl { kind, cause: None }),
226+
inner: Box::new(ErrorImpl {
227+
kind,
228+
cause: None,
229+
#[cfg(all(feature = "client", any(feature = "http1", feature = "http2")))]
230+
connect_info: None,
231+
}),
216232
}
217233
}
218234

@@ -221,6 +237,12 @@ impl Error {
221237
self
222238
}
223239

240+
#[cfg(all(feature = "client", any(feature = "http1", feature = "http2")))]
241+
pub(super) fn with_client_connect_info(mut self, connect_info: Connected) -> Error {
242+
self.inner.connect_info = Some(connect_info);
243+
self
244+
}
245+
224246
#[cfg(any(all(feature = "http1", feature = "server"), feature = "ffi"))]
225247
pub(super) fn kind(&self) -> &Kind {
226248
&self.inner.kind

0 commit comments

Comments
 (0)