early error on peer's failure to determine file size
This commit is contained in:
@@ -38,6 +38,45 @@ use crate::{
|
||||
peer::{send_game_file_chunk, send_game_file_data},
|
||||
};
|
||||
|
||||
/// Custom error types for peer operations
|
||||
#[derive(Debug)]
|
||||
pub enum PeerError {
|
||||
FileSizeDetermination {
|
||||
path: String,
|
||||
source: std::io::Error,
|
||||
},
|
||||
GameDirNotSet,
|
||||
Other(eyre::Report),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for PeerError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
PeerError::FileSizeDetermination { path, source } => {
|
||||
write!(f, "Failed to determine file size for {path}: {source}")
|
||||
}
|
||||
PeerError::GameDirNotSet => write!(f, "Game directory not set"),
|
||||
PeerError::Other(err) => write!(f, "General error: {err}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for PeerError {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match self {
|
||||
PeerError::FileSizeDetermination { source, .. } => Some(source),
|
||||
PeerError::Other(err) => Some(err.root_cause()),
|
||||
PeerError::GameDirNotSet => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<eyre::Report> for PeerError {
|
||||
fn from(err: eyre::Report) -> Self {
|
||||
PeerError::Other(err)
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize and start the peer system
|
||||
/// This function replaces the main.rs entry point and allows the peer to be started from other crates
|
||||
pub fn start_peer(
|
||||
@@ -1489,6 +1528,15 @@ async fn handle_peer_stream(
|
||||
id,
|
||||
file_descriptions,
|
||||
},
|
||||
Err(PeerError::FileSizeDetermination { path, source }) => {
|
||||
let error_msg = format!(
|
||||
"Failed to determine file size for {path}: {source}"
|
||||
);
|
||||
log::error!(
|
||||
"File size determination error for game {id}: {error_msg}"
|
||||
);
|
||||
Response::InternalPeerError(error_msg)
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!(
|
||||
"Failed to get game file descriptions for {id}: {e}"
|
||||
@@ -1754,6 +1802,9 @@ async fn request_game_details_from_peer(
|
||||
Response::GameNotFound(_) => {
|
||||
eyre::bail!("peer {peer_addr} does not have game {game_id}")
|
||||
}
|
||||
Response::InternalPeerError(error_msg) => {
|
||||
eyre::bail!("peer {peer_addr} reported internal error: {error_msg}")
|
||||
}
|
||||
_ => eyre::bail!("unexpected response from {peer_addr}: {response:?}"),
|
||||
}
|
||||
}
|
||||
@@ -1855,12 +1906,15 @@ async fn ping_peer(peer_addr: SocketAddr) -> eyre::Result<bool> {
|
||||
async fn get_game_file_descriptions(
|
||||
game_id: &str,
|
||||
game_dir: &str,
|
||||
) -> eyre::Result<Vec<GameFileDescription>> {
|
||||
) -> Result<Vec<GameFileDescription>, PeerError> {
|
||||
let base_dir = PathBuf::from(game_dir);
|
||||
let game_path = base_dir.join(game_id);
|
||||
|
||||
if !game_path.exists() {
|
||||
eyre::bail!("Game directory does not exist: {}", game_path.display());
|
||||
return Err(PeerError::Other(eyre::eyre!(
|
||||
"Game directory does not exist: {}",
|
||||
game_path.display()
|
||||
)));
|
||||
}
|
||||
|
||||
let mut file_descriptions = Vec::new();
|
||||
@@ -1889,7 +1943,10 @@ async fn get_game_file_descriptions(
|
||||
Ok(metadata) => metadata.len(),
|
||||
Err(e) => {
|
||||
log::error!("Failed to read metadata for {relative_path}: {e}");
|
||||
eyre::bail!("Failed to read metadata for {relative_path}: {e}");
|
||||
return Err(PeerError::FileSizeDetermination {
|
||||
path: relative_path.clone(),
|
||||
source: e,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -31,6 +31,7 @@ pub enum Response {
|
||||
InvalidRequest(Bytes, String),
|
||||
EncodingError(String),
|
||||
DecodingError(Bytes, String),
|
||||
InternalPeerError(String),
|
||||
}
|
||||
|
||||
// Add Message trait
|
||||
|
||||
Reference in New Issue
Block a user