diff options
author | Matthias Beyer <matthias.beyer@atos.net> | 2021-05-12 13:28:12 +0200 |
---|---|---|
committer | Matthias Beyer <matthias.beyer@atos.net> | 2021-05-12 14:24:53 +0200 |
commit | 53870e95dc563a50a13861aedcf98fbf4a176abc (patch) | |
tree | e0c88abace86887544b089f9bf04cb52923eea75 /src | |
parent | 7e6b65ea3d72231c5f7181b70087b9b97ca69222 (diff) |
Report download errors gracefully
This patch changes the implementation of the "source download" subcommand so
that download errors are reported in the progress bar message, instead of
dropping the bar silently (which resulted in errors not being that visible to
the user).
Signed-off-by: Matthias Beyer <matthias.beyer@atos.net>
Tested-by: Matthias Beyer <matthias.beyer@atos.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/commands/source.rs | 86 |
1 files changed, 53 insertions, 33 deletions
diff --git a/src/commands/source.rs b/src/commands/source.rs index 7ba1b4d..14e1728 100644 --- a/src/commands/source.rs +++ b/src/commands/source.rs @@ -260,44 +260,64 @@ pub async fn download( if source_path_exists && !force { Err(anyhow!("Source exists: {}", source.path().display())) } else { - if source_path_exists { - let _ = source.remove_file().await?; - } + async fn perform_download(source: &SourceEntry, bar: &indicatif::ProgressBar) -> Result<()> { + trace!("Creating: {:?}", source); + let file = source.create().await.with_context(|| { + anyhow!( + "Creating source file destination: {}", + source.path().display() + ) + })?; + + let mut file = tokio::io::BufWriter::new(file); + let response = match reqwest::get(source.url().as_ref()).await { + Ok(resp) => resp, + Err(e) => { + bar.finish_with_message(format!("Failed: {}", source.url())); + return Err(e).with_context(|| anyhow!("Downloading '{}'", source.url())) + } + }; - trace!("Creating: {:?}", source); - let file = source.create().await.with_context(|| { - anyhow!( - "Creating source file destination: {}", - source.path().display() - ) - })?; - - let mut file = tokio::io::BufWriter::new(file); - let response = reqwest::get(source.url().as_ref()) - .await - .with_context(|| anyhow!("Downloading '{}'", source.url()))?; - - if let Some(len) = response.content_length() { - bar.set_length(len); - } - let mut stream = reqwest::get(source.url().as_ref()).await?.bytes_stream(); - let mut bytes_written = 0; - while let Some(bytes) = stream.next().await { - let bytes = bytes?; - file.write_all(bytes.as_ref()).await?; - bytes_written += bytes.len(); - - bar.inc(bytes.len() as u64); if let Some(len) = response.content_length() { - bar.set_message(format!("Downloading {} ({}/{} bytes)", source.url(), bytes_written, len)); - } else { - bar.set_message(format!("Downloading {} ({} bytes)", source.url(), bytes_written)); + bar.set_length(len); + } + + let mut stream = reqwest::get(source.url().as_ref()).await?.bytes_stream(); + let mut bytes_written = 0; + while let Some(bytes) = stream.next().await { + let bytes = bytes?; + file.write_all(bytes.as_ref()).await?; + bytes_written += bytes.len(); + + bar.inc(bytes.len() as u64); + if let Some(len) = response.content_length() { + bar.set_message(format!("Downloading {} ({}/{} bytes)", source.url(), bytes_written, len)); + } else { + bar.set_message(format!("Downloading {} ({} bytes)", source.url(), bytes_written)); + } + } + + file.flush() + .await + .map_err(Error::from) + .map(|_| ()) + } + + if source_path_exists /* && force is implied by 'if' above*/ { + if let Err(e) = source.remove_file().await { + bar.finish_with_message(format!("Failed to remove existing file: {}", source.path().display())); + return Err(e) } } - file.flush().await?; - bar.finish_with_message(format!("Finished: {}", source.url())); - Ok(()) + + if let Err(e) = perform_download(&source, &bar).await { + bar.finish_with_message(format!("Failed: {}", source.url())); + Err(e) + } else { + bar.finish_with_message(format!("Finished: {}", source.url())); + Ok(()) + } } } }) |