diff --git a/src/feather/app.py b/src/feather/app.py index e67a9c7..d5500d5 100755 --- a/src/feather/app.py +++ b/src/feather/app.py @@ -10,7 +10,7 @@ from datetime import datetime from feather.config import Config from feather.client import GReaderSession, TTRSession, ClientSession, Article, ArticleId -from feather.data import FileArticle +from feather.data import FileArticle, InvalidArticleFileError async def sleep_min_max(min_sleep: float, max_sleep: float, stop_sleep_event: Event): @@ -53,7 +53,12 @@ class FeatherApp: """Iterate over all the articles in local storage""" config = self.config for json_path in config.json_root.glob("*.json"): - yield FileArticle(config, json_path) + try: + yield FileArticle(config, json_path) + except InvalidArticleFileError: + print( + f"WARNING: Skipping corrupted article file {json_path}. Delete this file and its associated HTML file (if it exists) to resolve this warning." + ) def remove_empty_categories(self): """Remove empty directories in the HTML directory""" @@ -154,11 +159,16 @@ class FeatherApp: article.write() new_articles += 1 else: - old_article = FileArticle(config, json_path) - if article.was_updated(old_article): - old_article.delete() - article.write() - updated_articles += 1 + try: + old_article = FileArticle(config, json_path) + if article.was_updated(old_article): + old_article.delete() + article.write() + updated_articles += 1 + except InvalidArticleFileError: + print( + f" WARNING: Skipping corrupted article file {json_path}. Delete this file and its associated HTML file (if it exists) to resolve this warning." + ) # Remove or mark-as-read articles that we didn't get from the server but are in the JSON directory removed_articles = 0 diff --git a/src/feather/data.py b/src/feather/data.py index 4117545..ff0cfc7 100644 --- a/src/feather/data.py +++ b/src/feather/data.py @@ -283,13 +283,19 @@ class Article(ABC): self.delete() # paths might change so we preemptively remove the old file self.write(recompute_paths=True) # rewrite JSON & HTML +class InvalidArticleFileError(ValueError): + pass class FileArticle(Article): def __init__(self, config: Config, json_path: Path) -> Article: self.config = config self.json_path = json_path - article_json = json.load(json_path.open("r")) + try: + article_json = json.load(json_path.open("r")) + except ValueError as e: + raise InvalidArticleFileError(f"Can't load article file {json_path}") from e + for field in article_json: setattr(self, field, article_json[field]) self.category = Category.fromdict(article_json["category"])