{"record":{"id":"b3ee53edc12b26ff","repo":"ytdl-org/youtube-dl","slug":"s-s-b3ee53","errorCode":null,"errorMessage":"%s: %s","messagePattern":"%s: %s","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/itv.py","lineNumber":46,"sourceCode":"    smuggle_url,\n    strip_or_none,\n    traverse_obj,\n    url_or_none,\n    urljoin,\n)\n\n\nclass ITVBaseIE(InfoExtractor):\n\n    def __handle_request_webpage_error(self, err, video_id=None, errnote=None, fatal=True):\n        if errnote is False:\n            return False\n        if errnote is None:\n            errnote = 'Unable to download webpage'\n\n        errmsg = '%s: %s' % (errnote, error_to_compat_str(err))\n        if fatal:\n            raise ExtractorError(errmsg, sys.exc_info()[2], cause=err, video_id=video_id)\n        else:\n            self._downloader.report_warning(errmsg)\n            return False\n\n    @staticmethod\n    def _vanilla_ua_header():\n        return {'User-Agent': 'Mozilla/5.0'}\n\n    def _download_webpage_handle(self, url, video_id, *args, **kwargs):\n        # specialised to (a) use vanilla UA (b) detect geo-block\n        params = self._downloader.params\n        nkwargs = {}\n        if (\n                'user_agent' not in params\n                and not any(re.match(r'(?i)user-agent\\s*:', h)\n                            for h in (params.get('headers') or []))\n                and 'User-Agent' not in (kwargs.get('headers') or {})):\n","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/itv.py#L28-L64","documentation":"This is ITVBaseIE's centralized wrapper around webpage-download failures: a '%s: %s' message pairing the errnote (default 'Unable to download webpage') with the underlying exception string. With fatal=True it re-raises as ExtractorError chaining the original cause; with fatal=False it degrades to a warning and returns False.","triggerScenarios":"_download_webpage_handle on itv.com URLs failing at the HTTP layer - timeouts, 4xx/5xx, TLS errors, or geo-block redirects - where the specialized ITV handler catches the request error and re-packages it.","commonSituations":"ITV Hub content requested from outside the UK (ITV geo-blocks aggressively), transient CDN errors, or ITV bot-detection refusing the vanilla 'Mozilla/5.0' user agent the extractor deliberately uses.","solutions":["Read the chained cause text after the colon - it names the real failure (timeout, 403, DNS).","For geo errors, access ITV from a UK IP.","Retry for transient network/CDN failures.","Update youtube-dl/yt-dlp if ITV changed its page/geo flow."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    ydl.extract_info(itv_url)\nexcept ExtractorError as e:\n    cause = e.cause\n    msg = str(e)\n    if 'Forbidden' in msg or '403' in msg or 'geo' in msg.lower():\n        skip('likely UK-only')\n    else:\n        retry_with_backoff(itv_url)","preventionTips":["Inspect e.cause for the underlying urllib/HTTP error before deciding to retry.","Restrict ITV jobs to UK egress IPs.","Set sane socket timeouts and per-URL retry caps in downloader params."],"tags":["http","network","extractor","itv","geo-restriction","wrapper"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}