diff --git a/src/obsidian_metadata/models/metadata.py b/src/obsidian_metadata/models/metadata.py index 8d02b22..43e2a94 100644 --- a/src/obsidian_metadata/models/metadata.py +++ b/src/obsidian_metadata/models/metadata.py @@ -240,7 +240,11 @@ class Frontmatter: return {} yaml = YAML(typ="safe") - frontmatter: dict = yaml.load(frontmatter_block) + yaml.allow_unicode = False + try: + frontmatter: dict = yaml.load(frontmatter_block) + except Exception as e: # noqa: BLE001 + raise AttributeError(e) from e for k in frontmatter: if frontmatter[k] is None: diff --git a/src/obsidian_metadata/models/notes.py b/src/obsidian_metadata/models/notes.py index 0e1bd25..ae090da 100644 --- a/src/obsidian_metadata/models/notes.py +++ b/src/obsidian_metadata/models/notes.py @@ -53,7 +53,12 @@ class Note: alerts.error(f"Note {self.note_path} not found. Exiting") raise typer.Exit(code=1) from e - self.frontmatter: Frontmatter = Frontmatter(self.file_content) + try: + self.frontmatter: Frontmatter = Frontmatter(self.file_content) + except AttributeError as e: + alerts.error(f"Note {self.note_path} has invalid frontmatter.\n{e}") + raise typer.Exit(code=1) from e + self.inline_tags: InlineTags = InlineTags(self.file_content) self.inline_metadata: InlineMetadata = InlineMetadata(self.file_content) self.original_file_content: str = self.file_content @@ -113,11 +118,10 @@ class Note: ) else: self.sub(f"{_k}::", f"{value_1}::") - else: - if re.search(key, _k) and re.search(value_1, _v): - _k = re.escape(_k) - _v = re.escape(_v) - self.sub(f"{_k}:: ?{_v}", f"{_k}:: {value_2}", is_regex=True) + elif re.search(key, _k) and re.search(value_1, _v): + _k = re.escape(_k) + _v = re.escape(_v) + self.sub(f"{_k}:: ?{_v}", f"{_k}:: {value_2}", is_regex=True) def add_metadata( # noqa: C901 self, @@ -151,9 +155,8 @@ class Note: new_values = [] if isinstance(value, list): new_values = [_v for _v in value if self.inline_metadata.add(key, _v)] - else: - if self.inline_metadata.add(key, value): - new_values = [value] + elif self.inline_metadata.add(key, value): + new_values = [value] if new_values: for value in new_values: @@ -164,9 +167,8 @@ class Note: new_values = [] if isinstance(value, list): new_values = [_v for _v in value if self.inline_tags.add(_v)] - else: - if self.inline_tags.add(value): - new_values = [value] + elif self.inline_tags.add(value): + new_values = [value] if new_values: for value in new_values: diff --git a/tests/fixtures/broken_frontmatter.md b/tests/fixtures/broken_frontmatter.md new file mode 100644 index 0000000..364580f --- /dev/null +++ b/tests/fixtures/broken_frontmatter.md @@ -0,0 +1,6 @@ +--- +tags: +invalid = = "content" +--- + +Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est la diff --git a/tests/metadata_test.py b/tests/metadata_test.py index b9221fc..9cc5d33 100644 --- a/tests/metadata_test.py +++ b/tests/metadata_test.py @@ -88,6 +88,22 @@ def test_frontmatter_create() -> None: } +def test_frontmatter_create_error() -> None: + """Test frontmatter creation error. + + GIVEN frontmatter content + WHEN frontmatter is invalid + THEN raise ValueError + """ + fn = """--- +tags: tag +invalid = = "content" +--- + """ + with pytest.raises(AttributeError): + Frontmatter(fn) + + def test_frontmatter_contains() -> None: """Test frontmatter contains.""" frontmatter = Frontmatter(FRONTMATTER_CONTENT) diff --git a/tests/notes_test.py b/tests/notes_test.py index 4849592..5796fb6 100644 --- a/tests/notes_test.py +++ b/tests/notes_test.py @@ -175,6 +175,18 @@ def test_add_metadata_frontmatter(sample_note) -> None: } +def test_add_metadata_frontmatter_error() -> None: + """Test adding metadata. + + GIVEN a note with broken frontmatter + WHEN the note is initialized + THEN a typer exit is raised + """ + broken_fm = Path("tests/fixtures/broken_frontmatter.md") + with pytest.raises(typer.Exit): + Note(note_path=broken_fm) + + def test_add_metadata_tag(sample_note) -> None: """Test adding inline tags.""" note = Note(note_path=sample_note)