fetch: surface underlying I/O error
The message that is returned by `gix-transport` for I/O errors can be unhelpful, since it does not provide the reason for what happened. Instead, surface the error so that it provides more detail for logging.
This commit is contained in:
parent
75b665ff3a
commit
3168107df9
|
|
@ -10,7 +10,7 @@ $ rad clone rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu --seed z6MknSLrJoTcukLrE435hVNQT4J
|
|||
Fetching rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu from the network, found 1 potential seed(s).
|
||||
✗ Target not met: could not fetch from [z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi], and required 1 more seed(s)
|
||||
! Warning: Failed to fetch from 1 seed(s).
|
||||
! Warning: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi: failed to perform fetch handshake: [..]
|
||||
! Warning: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi: an I/O error occurred during the fetch handshake (connection reset)
|
||||
✗ Error: no seeds found for rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ mod refs;
|
|||
mod stage;
|
||||
mod state;
|
||||
|
||||
use std::io;
|
||||
use std::time::Instant;
|
||||
|
||||
use gix_protocol::handshake;
|
||||
|
|
@ -28,8 +29,8 @@ use thiserror::Error;
|
|||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
#[error("failed to perform fetch handshake: {0}")]
|
||||
Handshake(#[from] Box<handshake::Error>),
|
||||
#[error(transparent)]
|
||||
Handshake(Box<HandshakeError>),
|
||||
#[error("failed to load `rad/id`")]
|
||||
Identity {
|
||||
#[source]
|
||||
|
|
@ -43,6 +44,20 @@ pub enum Error {
|
|||
ReplicateSelf,
|
||||
}
|
||||
|
||||
impl From<HandshakeError> for Error {
|
||||
fn from(err: HandshakeError) -> Self {
|
||||
Self::Handshake(Box::new(err))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum HandshakeError {
|
||||
#[error("failed to perform fetch handshake: {0}")]
|
||||
Gix(handshake::Error),
|
||||
#[error("an I/O error occurred during the fetch handshake ({0})")]
|
||||
Io(io::Error),
|
||||
}
|
||||
|
||||
/// Pull changes from the `remote`.
|
||||
///
|
||||
/// It is expected that the local peer has a copy of the repository
|
||||
|
|
@ -127,11 +142,24 @@ fn perform_handshake<R, S>(handle: &mut Handle<R, S>) -> Result<handshake::Outco
|
|||
where
|
||||
S: transport::ConnectionStream,
|
||||
{
|
||||
let result = handle.transport.handshake();
|
||||
|
||||
if let Err(err) = &result {
|
||||
log::warn!(target: "fetch", "Failed to perform handshake: {err}");
|
||||
}
|
||||
|
||||
Ok(result?)
|
||||
handle
|
||||
.transport
|
||||
.handshake()
|
||||
.map_err(handle_handshake_err)
|
||||
.map_err(Error::from)
|
||||
}
|
||||
|
||||
fn handle_handshake_err(err: handshake::Error) -> HandshakeError {
|
||||
let err = match err {
|
||||
handshake::Error::Transport(error) => match error {
|
||||
gix_transport::client::Error::Io(error) => HandshakeError::Io(error),
|
||||
err => HandshakeError::Gix(handshake::Error::Transport(err)),
|
||||
},
|
||||
err => {
|
||||
log::warn!(target: "fetch", "Failed to perform handshake: {err}");
|
||||
HandshakeError::Gix(err)
|
||||
}
|
||||
};
|
||||
log::warn!(target: "fetch", "{err}");
|
||||
err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,8 @@ where
|
|||
}
|
||||
|
||||
/// Perform the handshake with the server side.
|
||||
pub(crate) fn handshake(&mut self) -> Result<handshake::Outcome, Box<handshake::Error>> {
|
||||
#[allow(clippy::result_large_err)]
|
||||
pub(crate) fn handshake(&mut self) -> Result<handshake::Outcome, handshake::Error> {
|
||||
log::trace!(target: "fetch", "Performing handshake for {}", self.repo);
|
||||
let (read, write) = self.stream.open();
|
||||
gix_protocol::fetch::handshake(
|
||||
|
|
@ -98,7 +99,6 @@ where
|
|||
vec![],
|
||||
&mut progress::Discard,
|
||||
)
|
||||
.map_err(Box::new)
|
||||
}
|
||||
|
||||
/// Perform ls-refs with the server side.
|
||||
|
|
|
|||
Loading…
Reference in New Issue