From 64d66474474ddf8699b9b8bda2728ea9c0596208 Mon Sep 17 00:00:00 2001 From: Maximilian Roos <5635139+max-sixty@users.noreply.github.com> Date: Mon, 19 Feb 2024 08:21:46 -0800 Subject: [PATCH] Add the file reference on a YAML error message (#443) --- src/content/mod.rs | 7 +++++-- src/content/yaml.rs | 6 +++--- src/snapshot.rs | 30 +++++++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/content/mod.rs b/src/content/mod.rs index 514f0a58..2526dbf2 100644 --- a/src/content/mod.rs +++ b/src/content/mod.rs @@ -20,7 +20,7 @@ use std::fmt; /// An internal error type for content related errors. #[derive(Debug)] pub enum Error { - FailedParsingYaml, + FailedParsingYaml(Option), UnexpectedDataType, #[cfg(feature = "_cargo_insta_internal")] MissingField, @@ -29,7 +29,10 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Self::FailedParsingYaml => f.write_str("Failed parsing the provided YAML text"), + Self::FailedParsingYaml(None) => f.write_str("Failed parsing the provided YAML text"), + Self::FailedParsingYaml(Some(pathbuf)) => f.write_str( + format!("Failed parsing the YAML from {:?}", pathbuf.as_os_str()).as_str(), + ), Self::UnexpectedDataType => { f.write_str("The present data type wasn't what was expected") } diff --git a/src/content/yaml.rs b/src/content/yaml.rs index ede5a286..76ab9f13 100644 --- a/src/content/yaml.rs +++ b/src/content/yaml.rs @@ -4,11 +4,11 @@ use yaml_rust::{yaml::Hash as YamlObj, Yaml as YamlValue}; pub fn parse_str(s: &str) -> Result { let mut blobs = - yaml_rust::YamlLoader::load_from_str(s).map_err(|_| Error::FailedParsingYaml)?; + yaml_rust::YamlLoader::load_from_str(s).map_err(|_| Error::FailedParsingYaml(None))?; match (blobs.pop(), blobs.pop()) { (Some(blob), None) => from_yaml_blob(blob).map_err(Into::into), - _ => Err(Error::FailedParsingYaml), + _ => Err(Error::FailedParsingYaml(None)), } } @@ -36,7 +36,7 @@ fn from_yaml_blob(blob: YamlValue) -> Result { .collect::>()?; Ok(Content::Map(obj)) } - YamlValue::BadValue | YamlValue::Alias(_) => Err(Error::FailedParsingYaml), + YamlValue::BadValue | YamlValue::Alias(_) => Err(Error::FailedParsingYaml(None)), } } diff --git a/src/snapshot.rs b/src/snapshot.rs index 0674ca75..195ef5d6 100644 --- a/src/snapshot.rs +++ b/src/snapshot.rs @@ -286,7 +286,14 @@ impl Snapshot { break; } } - let content = yaml::parse_str(&buf)?; + let content = yaml::parse_str(&buf).map_err(|e| { + // Add file context to error + if matches!(e, content::Error::FailedParsingYaml(None)) { + content::Error::FailedParsingYaml(Some(p.to_path_buf())) + } else { + e + } + })?; MetaData::from_content(content)? // legacy format } else { @@ -884,3 +891,24 @@ fn test_inline_snapshot_value_newline() { // https://github.com/mitsuhiko/insta/issues/39 assert_eq!(get_inline_snapshot_value("\n"), ""); } + +#[test] +fn test_parse_yaml_error() { + use std::env::temp_dir; + let mut temp = temp_dir(); + temp.push("bad.yaml"); + let mut f = fs::File::create(temp.clone()).unwrap(); + + let invalid = r#"--- + This is invalid yaml: + { + { + --- + "#; + + f.write_all(invalid.as_bytes()).unwrap(); + + let error = format!("{}", Snapshot::from_file(temp.as_path()).unwrap_err()); + assert!(error.contains("Failed parsing the YAML from")); + assert!(error.contains("/bad.yaml")); +}