From 703926bca5ee16ac5779e220d2c278392b122bbd Mon Sep 17 00:00:00 2001 From: SergeantPanda Date: Thu, 11 Jun 2026 16:58:43 -0500 Subject: [PATCH] fix(m3u): improve RANGE_EXHAUSTED error reporting for provider mode - Introduced a new helper function to generate user-facing error messages for RANGE_EXHAUSTED failures, ensuring the fallback range is correctly displayed. - Updated tests to verify that the error message reflects the fallback range instead of the hidden auto_sync_channel_start, enhancing clarity for users. --- apps/m3u/tasks.py | 16 +++++++++++++--- apps/m3u/tests/test_sync_correctness.py | 24 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/apps/m3u/tasks.py b/apps/m3u/tasks.py index a4d863e9..90037c0f 100644 --- a/apps/m3u/tasks.py +++ b/apps/m3u/tasks.py @@ -1740,6 +1740,14 @@ def _pick_target_number( return _next_available_number(used_numbers, fixed_cursor, end=end_number) +def _range_exhausted_error(mode, start_number, end_number, fallback_start): + """User-facing range text for RANGE_EXHAUSTED failures.""" + range_start = ( + int(fallback_start) if mode == "provider" else int(start_number) + ) + return f"Channel number range {range_start}-{int(end_number)} is full" + + def _custom_properties_as_dict(value): """ Normalize a JSONField-backed custom_properties value into a dict. @@ -2454,9 +2462,11 @@ def sync_auto_channels(account_id, scan_start_time=None): "stream_id": stream.id, "group": channel_group.name, "reason": "RANGE_EXHAUSTED", - "error": ( - f"Channel number range " - f"{int(start_number)}-{int(end_number)} is full" + "error": _range_exhausted_error( + channel_numbering_mode, + start_number, + end_number, + channel_numbering_fallback, ), }) processed_stream_ids.add(stream.id) diff --git a/apps/m3u/tests/test_sync_correctness.py b/apps/m3u/tests/test_sync_correctness.py index beeeef0d..3cc24942 100644 --- a/apps/m3u/tests/test_sync_correctness.py +++ b/apps/m3u/tests/test_sync_correctness.py @@ -2494,6 +2494,30 @@ class ProviderNumberingHonorsProviderNumberTests(TestCase): manual.refresh_from_db() self.assertEqual(manual.channel_number, 88250.0) + def test_provider_fallback_exhaustion_reports_visible_start(self): + # RANGE_EXHAUSTED must cite the fallback range (channel_numbering_fallback + # to End), not the hidden auto_sync_channel_start left from another mode. + account = _make_account() + group = _make_group(name="PPV") + rel = _attach_group_to_account(account, group) + rel.auto_sync_channel_start = 5000 + rel.auto_sync_channel_end = 102 + rel.custom_properties = { + "channel_numbering_mode": "provider", + "channel_numbering_fallback": 100, + } + rel.save() + for i in range(4): + _make_stream(account, group, name=f"S{i}", tvg_id=f"s{i}") + + result = _sync(account) + + self.assertEqual(result["channels_created"], 3) + self.assertEqual(result["channels_failed"], 1) + error = result["failed_stream_details"][0]["error"] + self.assertIn("100-102", error) + self.assertNotIn("5000", error) + class CrossModeNumberingFieldTests(TestCase): """