From 29866ab03f79af98a3e71d101bfc9a41cff3d7f6 Mon Sep 17 00:00:00 2001 From: Nirvana Date: Thu, 24 Sep 2026 10:08:01 +0200 Subject: [PATCH] magentaeu: fix VOD --- .../providers/magentaeu/vod_errors.py | 12 +++++++++ .../providers/magentaeu/vod_manager.py | 26 +++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/lib/streaming_providers/providers/magentaeu/vod_errors.py b/lib/streaming_providers/providers/magentaeu/vod_errors.py index 0796f3b..58e44f1 100644 --- a/lib/streaming_providers/providers/magentaeu/vod_errors.py +++ b/lib/streaming_providers/providers/magentaeu/vod_errors.py @@ -88,6 +88,18 @@ class VodNotFoundError(VodError): """Content has been removed or never existed.""" +class VodBadRequestError(VodError): + """ + 400 -- malformed request for the endpoint called. + + Confirmed in production (not just capture): passing a component id + to `/home/page/{id}` returns 400, not 404. `get_category_children()`'s + page-then-component dispatch guess relies on this to know when its + first guess was wrong, since content_id alone doesn't reveal + whether it names a page or a component. + """ + + class VodRateLimitError(VodError): """429 -- caller should back off.""" diff --git a/lib/streaming_providers/providers/magentaeu/vod_manager.py b/lib/streaming_providers/providers/magentaeu/vod_manager.py index 07c39b5..5a2957b 100644 --- a/lib/streaming_providers/providers/magentaeu/vod_manager.py +++ b/lib/streaming_providers/providers/magentaeu/vod_manager.py @@ -74,6 +74,7 @@ from .constants import ( from .vod_errors import ( VodAccountVodDisabledError, VodAuthError, + VodBadRequestError, VodCatchupRequiredError, VodEntitlementError, VodError, @@ -212,10 +213,25 @@ class MagentaEUVodManager: if not content_id: return self.get_root_categories() + # Rails come back as components; a page id returns the rails on + # that page. We cannot tell from the id alone which one this is, + # so we try page first and fall back to component. + # + # FIXED (production evidence, not capture): the wrong-guess + # signal from bifrost is 400 Bad Request, NOT 404 as originally + # assumed. A live call to /home/page/{component_id} for a real + # rail id (e.g. "PREPORUKA UREDNIKA" -> 640f02fb55eb300001743795) + # returned 400. Catching only VodNotFoundError here meant every + # non-page content_id propagated a raw VodError instead of + # falling through to _get_component_assets -- i.e. every rail + # was unbrowsable. Both exception types are caught now. try: return self._get_page_rails(content_id) - except VodNotFoundError: - pass + except (VodNotFoundError, VodBadRequestError) as exc: + logger.debug( + f"[{self._country}] {content_id} is not a page " + f"({type(exc).__name__}), trying as a component instead" + ) return self._get_component_assets(content_id) @@ -750,6 +766,12 @@ class MagentaEUVodManager: raise VodEntitlementError(message, status=status, url=url) if status == 404: raise VodNotFoundError(message, status=status, url=url) + if status == 400: + # FIXED (production evidence): a component id passed to + # /home/page/{id} returns 400, not 404. get_category_children() + # relies on this being raised as a distinguishable type to + # know its page-vs-component guess was wrong. + raise VodBadRequestError(message, status=status, url=url) if status == 429: raise VodRateLimitError(message, status=status, url=url) if 500 <= status < 600: