From 81f95b67ad650b0ef3170c34b0177bd6a7b95891 Mon Sep 17 00:00:00 2001 From: Ruediger Klaehn Date: Tue, 16 Apr 2024 10:20:35 +0300 Subject: [PATCH] feat(iroh-bytes): add more context to errors add hash and offset/range as context for LeafHashMismatch and ParentHashMismatch errors --- iroh-bytes/src/provider.rs | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/iroh-bytes/src/provider.rs b/iroh-bytes/src/provider.rs index 0a383b5038..3c23b3684b 100644 --- a/iroh-bytes/src/provider.rs +++ b/iroh-bytes/src/provider.rs @@ -4,6 +4,7 @@ use std::time::Duration; use anyhow::{Context, Result}; use bao_tree::io::fsm::{encode_ranges_validated, Outboard}; +use bao_tree::io::EncodeError; use futures::future::BoxFuture; use iroh_base::rpc::RpcError; use iroh_io::stats::{ @@ -487,34 +488,50 @@ pub enum SentStatus { NotFound, } -/// Send a +/// Send a blob to the client. pub async fn send_blob( db: &D, - name: Hash, + hash: Hash, ranges: &RangeSpec, mut writer: W, ) -> Result<(SentStatus, u64, SliceReaderStats)> { - match db.get(&name).await? { + match db.get(&hash).await? { Some(entry) => { let outboard = entry.outboard().await?; let size = outboard.tree().size(); let mut file_reader = TrackingSliceReader::new(entry.data_reader().await?); writer.write(size.to_le_bytes().as_slice()).await?; - let res = encode_ranges_validated( + encode_ranges_validated( &mut file_reader, outboard, &ranges.to_chunk_ranges(), writer, ) - .await; - debug!("done sending blob {} {:?}", name, res); - res?; + .await + .map_err(|e| encode_error_to_anyhow(e, &hash))?; Ok((SentStatus::Sent, size, file_reader.stats())) } _ => { - debug!("blob not found {}", hex::encode(name)); + debug!("blob not found {}", hash.to_hex()); Ok((SentStatus::NotFound, 0, SliceReaderStats::default())) } } } + +fn encode_error_to_anyhow(err: EncodeError, hash: &Hash) -> anyhow::Error { + match err { + EncodeError::LeafHashMismatch(x) => anyhow::Error::from(EncodeError::LeafHashMismatch(x)) + .context(format!("hash {} offset {}", hash.to_hex(), x.to_bytes())), + EncodeError::ParentHashMismatch(n) => { + let r = n.chunk_range(); + anyhow::Error::from(EncodeError::ParentHashMismatch(n)).context(format!( + "hash {} range {}..{}", + hash.to_hex(), + r.start.to_bytes(), + r.end.to_bytes() + )) + } + e => anyhow::Error::from(e).context(format!("hash {}", hash.to_hex())), + } +}