Preserve metadata deserialize error details

This commit is contained in:
Bryan Helmkamp 2026-03-30 16:00:23 -04:00
parent e9d924fa63
commit bd82539516
No known key found for this signature in database
3 changed files with 36 additions and 3 deletions

View file

@ -47,7 +47,7 @@ impl<'a> BranchStore<'a> {
self.objects
.write_commit(empty_tree, &[], "initialize branch", &self.author)?;
self.objects.update_ref(&self.branch, commit_oid)?;
debug!(branch = %self.branch, "Created git storage branch");
debug!(branch = %self.branch, "Created checkpoint branch");
Ok(())
}
@ -74,7 +74,7 @@ impl<'a> BranchStore<'a> {
self.objects
.write_commit(new_tree, &[parent_oid], message, &self.author)?;
self.objects.update_ref(&self.branch, commit_oid)?;
debug!(branch = %self.branch, commit = %commit_oid, "Wrote git storage commit");
debug!(branch = %self.branch, commit = %commit_oid, "Wrote checkpoint commit");
Ok(commit_oid)
}

View file

@ -22,7 +22,7 @@ pub enum MetadataError {
#[error(transparent)]
Storage(#[from] Error),
#[error("deserialize {entity} on branch {branch}")]
#[error("deserialize {entity} on branch {branch}: {source}")]
Deserialize {
entity: &'static str,
branch: String,

View file

@ -362,6 +362,7 @@ pub type Result<T> = std::result::Result<T, FabroError>;
mod tests {
use super::*;
use crate::outcome::OutcomeExt;
use fabro_checkpoint::MetadataError;
use fabro_llm::error::ProviderErrorDetail;
#[test]
@ -432,6 +433,38 @@ mod tests {
assert!(err.is_err());
}
#[test]
fn metadata_checkpoint_deserialize_error_preserves_source_detail() {
let source = serde_json::from_str::<serde_json::Value>("not json").unwrap_err();
let source_message = source.to_string();
let fabro_error = FabroError::from(MetadataError::Deserialize {
entity: "checkpoint",
branch: "fabro/meta/run-1".to_string(),
source,
});
assert!(matches!(fabro_error, FabroError::Checkpoint(_)));
let message = fabro_error.to_string();
assert!(message.contains("deserialize checkpoint on branch fabro/meta/run-1"));
assert!(message.contains(&source_message));
}
#[test]
fn metadata_non_checkpoint_deserialize_error_maps_to_engine_with_source_detail() {
let source = serde_json::from_str::<serde_json::Value>("not json").unwrap_err();
let source_message = source.to_string();
let fabro_error = FabroError::from(MetadataError::Deserialize {
entity: "run record",
branch: "fabro/meta/run-1".to_string(),
source,
});
assert!(matches!(fabro_error, FabroError::Engine { .. }));
let message = fabro_error.to_string();
assert!(message.contains("deserialize run record on branch fabro/meta/run-1"));
assert!(message.contains(&source_message));
}
#[test]
fn cancelled_error_display() {
let err = FabroError::Cancelled;