From 2ae89930c0e344e1d6f9050eb8bdb86ad0a3f72a Mon Sep 17 00:00:00 2001
From: Eduardo Trujillo <ed@chromabits.com>
Date: Mon, 28 Nov 2022 12:15:37 -0800
Subject: [PATCH] fix: Gracefully handle feeds with invalid items

---
 src/parser/feedParser.ts | 33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/src/parser/feedParser.ts b/src/parser/feedParser.ts
index 5acb920..8b8d875 100644
--- a/src/parser/feedParser.ts
+++ b/src/parser/feedParser.ts
@@ -10,20 +10,13 @@ export default class FeedParser {
 	}
 
 	public async findItemByTitle(title: string, url: string): Promise<Episode> {
-		const body = await this.parseFeed(url);
-
-		const items = body.querySelectorAll("item");
+		const episodes = await this.getEpisodes(url);
 
-		const item = Array.from(items).find(item => {
-			const parsed = this.parseItem(item);
-			return parsed.title === title;
-		});
+		const episode = episodes.find(episode => episode.title === title);
 
-		if (!item) {
+		if (episode == null) {
 			throw new Error("Could not find episode");
 		}
-
-		const episode =  this.parseItem(item);
 		
 		const feed = await this.getFeed(url);
 
@@ -74,10 +67,21 @@ export default class FeedParser {
 	protected parsePage(page: Document): Episode[] {
 		const items = page.querySelectorAll("item");
 
-		return Array.from(items).map(this.parseItem.bind(this));
+		return Array.from(items).reduce(
+			(acc, rawItem) => {
+				const item = this.parseItem(rawItem);
+
+				if (item != null) {
+					return [item, ...acc];
+				}
+
+				return acc;
+			},
+			[],
+		);
 	}
 
-	protected parseItem(item: Element): Episode {
+	protected parseItem(item: Element): Episode | null {
 		const titleEl = item.querySelector("title");
 		const streamUrlEl = item.querySelector("enclosure");
 		const linkEl = item.querySelector("link");
@@ -86,8 +90,9 @@ export default class FeedParser {
 		const itunesImageEl = item.querySelector("image");
 
 		if (!titleEl || !streamUrlEl || !pubDateEl) {
-			console.log(titleEl, streamUrlEl, linkEl, descriptionEl, pubDateEl);
-			throw new Error("Invalid RSS feed");
+			console.log('Got invalid feed item', titleEl, streamUrlEl, linkEl, descriptionEl, pubDateEl);
+
+			return null;
 		}
 
 		const title = titleEl.textContent || "";
-- 
GitLab