Belga News feed produces no articles — RSS feed retired, discovery approach TBD #115
Labels
No labels
bug
devops
duplicate
enhancement
good first issue
layout
next major release
next minor release
question
research
testing
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lvl0/fedi-feed-router#115
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
The Belga News feed produces no articles. Root cause confirmed: the RSS feed no longer exists.
The discovery job runs normally and reports success, so this failed silently. The remaining work is deciding how to discover Belga articles without an RSS feed — that question is open and needs research before implementation.
Root cause
Feed config (prod)
The job is running (fetched that morning), so this is not a queue or scheduler problem.
The feed URL is dead
ArticleFetcher::getArticlesFromRssFeed()passes that HTML tosimplexml_load_string(), which fails, logs "Failed to parse RSS feed XML", and returns an empty collection. The job then completes and updateslast_fetched_at— hence the silent failure.No alternative feed exists
404 on all of:
/rss,/rss.xml,/feed.xml,/en/feed,/atom.xml,/index.xml.The homepage (200 OK) declares no
<link rel="alternate">RSS/Atom element. The public feed appears to have been retired.Why the VRT approach does not transfer
No Belga homepage parser exists — verified:
BelgaArticleParser,BelgaArticlePageParser,BelgaArticlePageParserTestVrtHomepageParserAdapteris the only implementation ofHomepageParserInterfaceconfig/feed.php→belga.parsershasarticleandarticle_page, nohomepagekey;type => 'rss'The site is client-side rendered. It is a Next.js app (27
/_next/references,__NEXT_DATA__present). Server-side fetch yields:__NEXT_DATA__payload ~2 KB, containing zero article slugsVrtHomepageParserworks by regex over server-rendered HTML. That approach will find nothing here.Other routes already ruled out:
/api/articles,/api/newsapi.belganewsagency.eu/sitemap.xmlbelgashare.be, lastmod 2025-09-30), no article URLs/sitemap_index.xmlOpen question — research before implementing
Do not start building a parser until the discovery source is settled. The options differ by an order of magnitude in cost:
belgashare.be— worth checking whether that or another Belga property exposes a usable feed.Once an approach is chosen, implementation follows the existing pattern: a thin adapter implementing
HomepageParserInterface(seeVrtHomepageParserAdapter), a parser class doing extraction, both registered inconfig/feed.phpunderbelga.parsers.homepage, withtypechanged fromrsstowebsite.Acceptance criteria
config/feed.php, feedtypeupdated towebsiteRelated
A feed whose URL 404s currently updates
last_fetched_atand reports success, with only a log warning — nothing surfaces in the UI and no notification fires.CheckFeedStalenessJoband theFEED_STALEnotification already exist and could plausibly cover "fetched repeatedly but returned zero articles". That gap applies to all feeds, not just Belga, and is worth its own ticket.Root cause found — the RSS feed is gone
Diagnostics from production and against the live site.
Feed config (prod)
The job is running (fetched this morning), so this is not a queue or scheduler problem.
The feed URL is dead
getArticlesFromRssFeed()passes that HTML tosimplexml_load_string(), which fails, logs "Failed to parse RSS feed XML", and returns an empty collection. The job then completes successfully and updateslast_fetched_at— which is why this failed silently with no visible error.No alternative feed exists
All returned 404:
/rss,/rss.xml,/feed.xml,/en/feed,/atom.xml,/index.xml.The homepage (200 OK) declares no
<link rel="alternate">RSS/Atom element. The site appears to have retired its public feed entirely.Switching to website scraping is harder than the VRT case
Confirmed first that no Belga homepage parser exists in any form:
BelgaArticleParser,BelgaArticlePageParser, andBelgaArticlePageParserTestVrtHomepageParserAdapteris the only class implementingHomepageParserInterfaceconfig/feed.phphasbelga.parserswitharticleandarticle_pagebut nohomepagekey, andtype => 'rss'The blocker: the site is client-side rendered
The homepage is a Next.js app (27
/_next/references,__NEXT_DATA__present). Fetching it server-side yields:__NEXT_DATA__payload is only ~2 KB and contains zero article slugsArticle content is loaded client-side after page load. A regex-over-HTML approach like
VrtHomepageParserwill find nothing.Other discovery routes checked:
/api/articles,/api/news→ 404api.belganewsagency.eu→ DNS does not resolve/sitemap.xml→ 200, but it is a sitemap index with a single stale entry (belgashare.be, lastmod 2025-09-30) and no article URLs/sitemap_index.xml→ 404Open question before implementation
Server-side scraping of the homepage is not viable as-is. Options, roughly in order of cost:
belgashare.be(referenced in their own sitemap) or another Belga property exposes a usable feed.Recommend option 1 first; it determines whether this is a small parser addition or a much larger piece of work.
Separate issue worth noting
A feed whose URL 404s updates
last_fetched_atand reports success. There is a warning in the log, but nothing surfaces in the UI and no notification fires. GivenCheckFeedStalenessJoband theFEED_STALEnotification already exist, a feed returning zero articles over repeated fetches arguably deserves the same treatment. That is a general robustness gap, not specific to Belga — suggest a separate ticket.No articles being discovered from the Belga News feedto Belga News feed produces no articles — RSS feed retired, discovery approach TBDApproach settled — option 1, public JSON API found
DevTools inspection found the endpoint the site uses to populate its article list.
The endpoint
Verified working server-side —
curlwith noOrigin, noReferer, no cookies, no auth returns200 application/json. The CORS headers are for the browser's benefit; they do not gate server-to-server requests.newsroomId=70identifies the Belga News Agency newsroom (it matchesnewsroomData.idin the site's__NEXT_DATA__).Response shape
contentis keyed by language code (en), which maps cleanly onto the existing$languageconstructor parameter in the parser adaptersoffset/countwith_links.nextprovided;countcan be raised above 6_meta.totalwas 14650 at time of writingArticle URLs
The API returns no URL field. Article pages are reachable by ID:
Verified 200 for IDs 35285, 35282, 35271, 35269. Other patterns (
/{id},/pressreleases/{id},belgashare.be/pressreleases/{id}) all 404.So
extractArticleUrls()builds URLs fromdata[].idrather than scraping hrefs.The existing article parser still works
Article pages are server-rendered enough for
BelgaArticlePageParser:og:titleandog:descriptionare present in the raw HTML and match the API values exactly. No changes needed toBelgaArticleParser/BelgaArticlePageParser.Sample data returned (fetched 2026-08-01):
Revised implementation plan
BelgaHomepageParser— calls the API, returns article URLs built from IDs. UnlikeVrtHomepageParserthis is JSON parsing, not regex over HTML, so it is more robust.BelgaHomepageParserAdapter— implementsHomepageParserInterface, followsVrtHomepageParserAdapter, takes$languageand maps it to thelanguage=query parameter.config/feed.php— addbelga.parsers.homepage, changebelga.typefromrsstowebsite, update theenURL.type→website, and the URL to the homepage.Open questions for implementation
countvalue — the site requests 6.defaults.max_articles_per_fetchinconfig/feed.phpis 50. Worth confirming the API accepts a largercountrather than assuming.start/endparameters — appear to accept date bounds; could be used to fetch only recent articles rather than paginating from the newest.