| @@ -6,6 +6,7 @@ use std::{ · 5 unmodified lines |
| 6 | }; | 6 | }; |
| 7 | | 7 | |
| 8 | use anyhow::{Result, anyhow}; | 8 | use anyhow::{Result, anyhow}; |
| | 9 | use gix::error::{ErrorExt, NotFoundError, message}; |
| 9 | use gix::{ | 10 | use gix::{ |
| 10 | NestedProgress, | 11 | NestedProgress, |
| 11 | hash::ObjectId, | 12 | hash::ObjectId, |
| @@ -64,32 +65,6 @@ impl From<SafetyCheck> for pack::index::traverse::SafetyCheck { · 52 unmodified lines |
| 64 | } | 65 | } |
| 65 | } | 66 | } |
| 66 | | 67 | |
| 67 | #[derive(Debug, thiserror::Error)] | | |
| 68 | enum Error { | | |
| 69 | #[error("An IO error occurred while writing an object")] | | |
| 70 | Io(#[from] std::io::Error), | | |
| 71 | #[error("An object could not be written to the database")] | | |
| 72 | OdbWrite(#[from] loose::write::Error), | | |
| 73 | #[error("Failed to write {kind} object {id}")] | | |
| 74 | Write { | | |
| 75 | source: Box<dyn std::error::Error + Send + Sync>, | | |
| 76 | kind: object::Kind, | | |
| 77 | id: ObjectId, | | |
| 78 | }, | | |
| 79 | #[error("Object didn't verify after right after writing it")] | | |
| 80 | Verify(#[source] std::io::Error), | | |
| 81 | #[error("{kind} object wasn't re-encoded without change")] | | |
| 82 | ObjectEncodeMismatch { | | |
| 83 | #[source] | | |
| 84 | source: gix::hash::verify::Error, | | |
| 85 | kind: object::Kind, | | |
| 86 | }, | | |
| 87 | #[error("The recently written file for loose object {id} could not be found")] | | |
| 88 | WrittenFileMissing { id: ObjectId }, | | |
| 89 | #[error("The recently written file for loose object {id} cold not be read")] | | |
| 90 | WrittenFileCorrupt { source: loose::find::Error, id: ObjectId }, | | |
| 91 | } | | |
| 92 | | | |
| 93 | #[expect( | 68 | #[expect( |
| 94 | clippy::large_enum_variant, | 69 | clippy::large_enum_variant, |
| 95 | reason = "will be removed once `gix-error` is used consistently" | 70 | reason = "will be removed once `gix-error` is used consistently" |
| @@ -228,11 +203,15 @@ pub fn pack_or_pack_index( · 132 unmodified lines |
| 228 | .flatten(); | 203 | .flatten(); |
| 229 | let mut read_buf = Vec::new(); | 204 | let mut read_buf = Vec::new(); |
| 230 | move |object_kind, buf, index_entry, progress| { | 205 | move |object_kind, buf, index_entry, progress| { |
| 231 | let written_id = out.write_buf(object_kind, buf).map_err(|err| Error::Write { | 206 | let written_id = out |
| 232 | source: err.into(), | 207 | .write_buf(object_kind, buf) |
| 233 | kind: object_kind, | 208 | .map_err(|err| { |
| 234 | id: index_entry.oid, | 209 | err.raise(message!( |
| 235 | })?; | 210 | "Failed to write {object_kind} object {}", |
| | 211 | index_entry.oid |
| | 212 | )) |
| | 213 | .into_error() |
| | 214 | })?; |
| 236 | if let Err(err) = written_id.verify(&index_entry.oid) { | 215 | if let Err(err) = written_id.verify(&index_entry.oid) { |
| 237 | if let object::Kind::Tree = object_kind { | 216 | if let object::Kind::Tree = object_kind { |
| 238 | progress.info(format!( | 217 | progress.info(format!( |
| @@ -240,22 +219,28 @@ pub fn pack_or_pack_index( · 1 unmodified line |
| 240 | index_entry.oid, written_id | 219 | index_entry.oid, written_id |
| 241 | )); | 220 | )); |
| 242 | } else { | 221 | } else { |
| 243 | return Err(Error::ObjectEncodeMismatch { | 222 | return Err(err |
| 244 | source: err, | 223 | .and_raise(message!("{object_kind} object wasn't re-encoded without change")) |
| 245 | kind: object_kind, | 224 | .into_error()); |
| 246 | }); | | |
| 247 | } | 225 | } |
| 248 | } | 226 | } |
| 249 | if let Some(verifier) = loose_odb.as_ref() { | 227 | if let Some(verifier) = loose_odb.as_ref() { |
| 250 | let obj = verifier | 228 | let obj = verifier |
| 251 | .try_find(&written_id, &mut read_buf) | 229 | .try_find(&written_id, &mut read_buf) |
| 252 | .map_err(|err| Error::WrittenFileCorrupt { | 230 | .map_err(|err| { |
| 253 | source: err, | 231 | err.and_raise(message!( |
| 254 | id: written_id, | 232 | "The recently written file for loose object {written_id} could not be read" |
| | 233 | )) |
| | 234 | .into_error() |
| 255 | })? | 235 | })? |
| 256 | .ok_or(Error::WrittenFileMissing { id: written_id })?; | 236 | .ok_or_else(|| { |
| 257 | obj.verify_checksum(&written_id) | 237 | NotFoundError::new(format!( |
| 258 | .map_err(|err| Error::Verify(std::io::Error::other(err.into_error())))?; | 238 | "The recently written file for loose object {written_id} could not be found" |
| | 239 | )) |
| | 240 | .raise() |
| | 241 | .into_error() |
| | 242 | })?; |
| | 243 | obj.verify_checksum(&written_id).map_err(gix::Exn::into_error)?; |
| 259 | } | 244 | } |
| 260 | Ok(()) | 245 | Ok(()) |
| 261 | } | 246 | } |