##// END OF EJS Templates
rust: don't swallow valuable error information...
Raphaël Gomès -
r50269:455fce57 stable
parent child Browse files
Show More
@@ -49,18 +49,20 b' impl From<NodeMapError> for RevlogError '
49 fn from(error: NodeMapError) -> Self {
49 fn from(error: NodeMapError) -> Self {
50 match error {
50 match error {
51 NodeMapError::MultipleResults => RevlogError::AmbiguousPrefix,
51 NodeMapError::MultipleResults => RevlogError::AmbiguousPrefix,
52 NodeMapError::RevisionNotInIndex(_) => RevlogError::corrupted(),
52 NodeMapError::RevisionNotInIndex(rev) => RevlogError::corrupted(
53 format!("nodemap point to revision {} not in index", rev),
54 ),
53 }
55 }
54 }
56 }
55 }
57 }
56
58
57 fn corrupted() -> HgError {
59 fn corrupted<S: AsRef<str>>(context: S) -> HgError {
58 HgError::corrupted("corrupted revlog")
60 HgError::corrupted(format!("corrupted revlog, {}", context.as_ref()))
59 }
61 }
60
62
61 impl RevlogError {
63 impl RevlogError {
62 fn corrupted() -> Self {
64 fn corrupted<S: AsRef<str>>(context: S) -> Self {
63 RevlogError::Other(corrupted())
65 RevlogError::Other(corrupted(context))
64 }
66 }
65 }
67 }
66
68
@@ -329,7 +331,8 b' impl Revlog {'
329 &self,
331 &self,
330 rev: Revision,
332 rev: Revision,
331 ) -> Result<RevlogEntry, HgError> {
333 ) -> Result<RevlogEntry, HgError> {
332 return self.get_entry(rev).map_err(|_| corrupted());
334 self.get_entry(rev)
335 .map_err(|_| corrupted(format!("revision {} out of range", rev)))
333 }
336 }
334 }
337 }
335
338
@@ -449,7 +452,10 b" impl<'a> RevlogEntry<'a> {"
449 ) {
452 ) {
450 Ok(data)
453 Ok(data)
451 } else {
454 } else {
452 Err(corrupted())
455 Err(corrupted(format!(
456 "hash check failed for revision {}",
457 self.rev
458 )))
453 }
459 }
454 }
460 }
455
461
@@ -478,7 +484,10 b" impl<'a> RevlogEntry<'a> {"
478 // zstd data.
484 // zstd data.
479 b'\x28' => Ok(Cow::Owned(self.uncompressed_zstd_data()?)),
485 b'\x28' => Ok(Cow::Owned(self.uncompressed_zstd_data()?)),
480 // A proper new format should have had a repo/store requirement.
486 // A proper new format should have had a repo/store requirement.
481 _format_type => Err(corrupted()),
487 format_type => Err(corrupted(format!(
488 "unknown compression header '{}'",
489 format_type
490 ))),
482 }
491 }
483 }
492 }
484
493
@@ -486,12 +495,16 b" impl<'a> RevlogEntry<'a> {"
486 let mut decoder = ZlibDecoder::new(self.bytes);
495 let mut decoder = ZlibDecoder::new(self.bytes);
487 if self.is_delta() {
496 if self.is_delta() {
488 let mut buf = Vec::with_capacity(self.compressed_len as usize);
497 let mut buf = Vec::with_capacity(self.compressed_len as usize);
489 decoder.read_to_end(&mut buf).map_err(|_| corrupted())?;
498 decoder
499 .read_to_end(&mut buf)
500 .map_err(|e| corrupted(e.to_string()))?;
490 Ok(buf)
501 Ok(buf)
491 } else {
502 } else {
492 let cap = self.uncompressed_len.max(0) as usize;
503 let cap = self.uncompressed_len.max(0) as usize;
493 let mut buf = vec![0; cap];
504 let mut buf = vec![0; cap];
494 decoder.read_exact(&mut buf).map_err(|_| corrupted())?;
505 decoder
506 .read_exact(&mut buf)
507 .map_err(|e| corrupted(e.to_string()))?;
495 Ok(buf)
508 Ok(buf)
496 }
509 }
497 }
510 }
@@ -500,15 +513,15 b" impl<'a> RevlogEntry<'a> {"
500 if self.is_delta() {
513 if self.is_delta() {
501 let mut buf = Vec::with_capacity(self.compressed_len as usize);
514 let mut buf = Vec::with_capacity(self.compressed_len as usize);
502 zstd::stream::copy_decode(self.bytes, &mut buf)
515 zstd::stream::copy_decode(self.bytes, &mut buf)
503 .map_err(|_| corrupted())?;
516 .map_err(|e| corrupted(e.to_string()))?;
504 Ok(buf)
517 Ok(buf)
505 } else {
518 } else {
506 let cap = self.uncompressed_len.max(0) as usize;
519 let cap = self.uncompressed_len.max(0) as usize;
507 let mut buf = vec![0; cap];
520 let mut buf = vec![0; cap];
508 let len = zstd::block::decompress_to_buffer(self.bytes, &mut buf)
521 let len = zstd::block::decompress_to_buffer(self.bytes, &mut buf)
509 .map_err(|_| corrupted())?;
522 .map_err(|e| corrupted(e.to_string()))?;
510 if len != self.uncompressed_len as usize {
523 if len != self.uncompressed_len as usize {
511 Err(corrupted())
524 Err(corrupted("uncompressed length does not match"))
512 } else {
525 } else {
513 Ok(buf)
526 Ok(buf)
514 }
527 }
@@ -107,7 +107,10 b' py_class!(pub class MixedIndex |py| {'
107 String::from_utf8_lossy(node.data(py)).to_string()
107 String::from_utf8_lossy(node.data(py)).to_string()
108 };
108 };
109
109
110 let prefix = NodePrefix::from_hex(&node_as_string).map_err(|_| PyErr::new::<ValueError, _>(py, "Invalid node or prefix"))?;
110 let prefix = NodePrefix::from_hex(&node_as_string)
111 .map_err(|_| PyErr::new::<ValueError, _>(
112 py, format!("Invalid node or prefix '{}'", node_as_string))
113 )?;
111
114
112 nt.find_bin(idx, prefix)
115 nt.find_bin(idx, prefix)
113 // TODO make an inner API returning the node directly
116 // TODO make an inner API returning the node directly
@@ -517,10 +517,13 b' fn unsure_is_modified('
517 }
517 }
518 let filelog = repo.filelog(hg_path)?;
518 let filelog = repo.filelog(hg_path)?;
519 let fs_len = fs_metadata.len();
519 let fs_len = fs_metadata.len();
520 let filelog_entry =
520 let file_node = entry.node_id()?;
521 filelog.entry_for_node(entry.node_id()?).map_err(|_| {
521 let filelog_entry = filelog.entry_for_node(file_node).map_err(|_| {
522 HgError::corrupted("filelog missing node from manifest")
522 HgError::corrupted(format!(
523 })?;
523 "filelog missing node {:?} from manifest",
524 file_node
525 ))
526 })?;
524 if filelog_entry.file_data_len_not_equal_to(fs_len) {
527 if filelog_entry.file_data_len_not_equal_to(fs_len) {
525 // No need to read file contents:
528 // No need to read file contents:
526 // it cannot be equal if it has a different length.
529 // it cannot be equal if it has a different length.
General Comments 0
You need to be logged in to leave comments. Login now