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

Code before:
            'timestamp': 1758340800,
            'release_timestamp': 1758254400,
            'release_date': '20250919',
            'upload_date': '20250920',
        },
    }]

    def _download_api_json(self, video_id):
        return traverse_obj(self._download_json(
            f'https://www.cbc.ca/listen/api/v1/clips/{video_id}', video_id), 'data', {dict})

    def _extract_webpage_data(self, url, video_id):
        webpage = self._download_webpage(url, video_id)
        preloaded_state = self._search_json(
            r'window\.__PRELOADED_STATE__\s*=', webpage, 'preloaded state',
            video_id, transform_source=js_to_json)

        return traverse_obj(preloaded_state, (
            ('podcastDetailData', 'showDetailData'), ..., 'episodes',
            lambda _, v: str(v['clipID']) == video_id, any, {require('episode data')}))

    def _real_extract(self, url):
        video_id = self._match_id(url)
        data = None
        with contextlib.suppress(ExtractorError):
            data = self._download_api_json(video_id=video_id)
        if not data:
            self.report_warning('Api returned no data. Falling back to webpage parsing')
            data = self._extract_webpage_data(url, video_id)

        return {
            'id': video_id,
            **traverse_obj(data, {
                'url': (('src', 'url'), {url_or_none}, any),
                'title': ('title', {str}),
                'description': ('description', {str}),
                'release_timestamp': ('releasedAt', {int_or_none(scale=1000)}),
                'timestamp': ('airdate', {int_or_none(scale=1000)}),
                'duration': ('duration', {int_or_none}),
            }),
        }


Review comment (suggestion):
Just inline this with `fatal=False`
```suggestion
        data = traverse_obj(self._download_json(
            f'https://www.cbc.ca/listen/api/v1/clips/{video_id}', video_id, fatal=False), 'data', {dict})```

Code after:
            'release_timestamp': 1758254400,
            'release_date': '20250919',
            'upload_date': '20250920',
        },
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url)

        response = self._download_json(
            f'https://www.cbc.ca/listen/api/v1/clips/{video_id}', video_id, fatal=False)
        data = traverse_obj(response, ('data', {dict}))
        if not data:
            self.report_warning('API failed to return data. Falling back to webpage parsing')
            webpage = self._download_webpage(url, video_id)
            preloaded_state = self._search_json(
                r'window\.__PRELOADED_STATE__\s*=', webpage, 'preloaded state',
                video_id, transform_source=js_to_json)
            data = traverse_obj(preloaded_state, (
                ('podcastDetailData', 'showDetailData'), ..., 'episodes',
                lambda _, v: str(v['clipID']) == video_id, any, {require('episode data')}))

        return {
            'id': video_id,
            **traverse_obj(data, {
                'url': (('src', 'url'), {url_or_none}, any),
                'title': ('title', {str}),
                'description': ('description', {str}),
                'release_timestamp': ('releasedAt', {int_or_none(scale=1000)}),
                'timestamp': ('airdate', {int_or_none(scale=1000)}),
                'duration': ('duration', {int_or_none}),
            }),
        }