Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/dropout.py (Python)

Code before:
            }
        },
        {
            'url': 'https://www.dropout.tv/dimension-20-shriek-week',
            'note': 'Single-season series',
            'playlist_count': 4,
            'info_dict': {
                'id': 'dimension-20-shriek-week-season-1',
                'title': 'Dimension 20 Shriek Week - Season 1'
            }
        },
        {
            'url': 'https://www.dropout.tv/breaking-news-no-laugh-newsroom/season:3',
            'note': 'Multi-season series with season in the url that requires pagination',
            'playlist_count': 25,
            'info_dict': {
                'id': 'breaking-news-no-laugh-newsroom-season-3',
                'title': 'Breaking News No Laugh Newsroom - Season 3'
            }
        }
    ]

    def _fetch_page(self, url, season_id, page):
        page += 1
        webpage = self._download_webpage(
            f'{url}?page={page}', season_id, note=f'Downloading page {page}')
        yield from [self.url_result(item_url, DropoutIE) for item_url in traverse_obj(
            get_elements_html_by_class('browse-item-link', webpage), (..., {extract_attributes}, 'href'))]

    def _real_extract(self, url):
        season_id = self._match_id(url)
        season_num = self._match_valid_url(url).group('season') or 1
        season_title = season_id.replace('-', ' ').title()

        return self.playlist_result(
            OnDemandPagedList(functools.partial(self._fetch_page, url, season_id), self._PAGE_SIZE),
            f'{season_id}-season-{season_num}', f'{season_title} - Season {season_num}')


Review comment (bug):
My bad, I was wrong. yt-dlp will catch the error and continue with playlist extraction, but the extractor & tests do fail. Let's do this then:
```suggestion
        webpage = self._download_webpage(
            f'{url}?page={page}', season_id, note=f'Downloading page {page}', expected_status=400)
```

Code after:
            }
        },
        {
            'url': 'https://www.dropout.tv/dimension-20-shriek-week',
            'note': 'Single-season series',
            'playlist_count': 4,
            'info_dict': {
                'id': 'dimension-20-shriek-week-season-1',
                'title': 'Dimension 20 Shriek Week - Season 1'
            }
        },
        {
            'url': 'https://www.dropout.tv/breaking-news-no-laugh-newsroom/season:3',
            'note': 'Multi-season series with season in the url that requires pagination',
            'playlist_count': 25,
            'info_dict': {
                'id': 'breaking-news-no-laugh-newsroom-season-3',
                'title': 'Breaking News No Laugh Newsroom - Season 3'
            }
        }
    ]

    def _fetch_page(self, url, season_id, page):
        page += 1
        webpage = self._download_webpage(
            f'{url}?page={page}', season_id, note=f'Downloading page {page}', expected_status={400})
        yield from [self.url_result(item_url, DropoutIE) for item_url in traverse_obj(
            get_elements_html_by_class('browse-item-link', webpage), (..., {extract_attributes}, 'href'))]

    def _real_extract(self, url):
        season_id = self._match_id(url)
        season_num = self._match_valid_url(url).group('season') or 1
        season_title = season_id.replace('-', ' ').title()

        return self.playlist_result(
            OnDemandPagedList(functools.partial(self._fetch_page, url, season_id), self._PAGE_SIZE),
            f'{season_id}-season-{season_num}', f'{season_title} - Season {season_num}')