{"record":{"id":"0bd6488d4196df5e","repo":"NanmiCoder/MediaCrawler","slug":"not-match-kuaidaili-proxy-info","errorCode":null,"errorMessage":"not match kuaidaili proxy info","messagePattern":"not match kuaidaili proxy info","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"proxy/providers/kuaidl_proxy.py","lineNumber":63,"sourceCode":"\n\ndef parse_kuaidaili_proxy(proxy_info: str) -> KuaidailiProxyModel:\n    \"\"\"\n    Parse KuaiDaili IP information\n    Args:\n        proxy_info:\n\n    Returns:\n\n    \"\"\"\n    proxies: List[str] = proxy_info.split(\":\")\n    if len(proxies) != 2:\n        raise Exception(\"not invalid kuaidaili proxy info\")\n\n    pattern = r'(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}):(\\d{1,5}),(\\d+)'\n    match = re.search(pattern, proxy_info)\n    if not match.groups():\n        raise Exception(\"not match kuaidaili proxy info\")\n\n    return KuaidailiProxyModel(\n        ip=match.groups()[0],\n        port=int(match.groups()[1]),\n        expire_ts=int(match.groups()[2])\n    )\n\n\nclass KuaiDaiLiProxy(ProxyProvider):\n    def __init__(self, kdl_user_name: str, kdl_user_pwd: str, kdl_secret_id: str, kdl_signature: str):\n        \"\"\"\n\n        Args:\n            kdl_user_name:\n            kdl_user_pwd:\n        \"\"\"\n        self.kdl_user_name = kdl_user_name\n        self.kdl_user_pwd = kdl_user_pwd","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/NanmiCoder/MediaCrawler/blob/d6f7c5bb906b6dac40ddf343ef9e26438a3de092/proxy/providers/kuaidl_proxy.py#L45-L81","documentation":"Intended to fire when re.search() finds no capture groups for the pattern '(ip):(port),(digits)' in the KuaiDaiLi proxy string. In practice this raise is dead code: when the pattern does not match, re.search() returns None and match.groups() raises AttributeError ('NoneType' object has no attribute 'groups') on the line above. The only way to see this exact message is a zero-group match, which this regex cannot produce.","triggerScenarios":"A proxy_list entry whose ip:port,expire shape deviates from the regex — hostname instead of dotted-quad IP, port longer than 5 digits, non-digit expire field, or extra whitespace. Instead of this message you will typically see the AttributeError from the same region; the underlying input condition is identical.","commonSituations":"KuaiDaiLi returning a domain-based proxy entry, a truncated response due to encoding issues, or a proxy string built by hand in tests that does not match the wire format.","solutions":["Fix the guard order: check `if match is None:` before touching match.groups() so a clean error is raised instead of AttributeError","Log the offending proxy_info value when parsing fails to identify which entry from proxy_list is malformed","Validate the entry against the regex yourself before passing it in: re.search(r'(\\d{1,3}\\.){3}\\d{1,3}:\\d{1,5},\\d+', entry)","If entries are hostnames, extend the pattern to accept [\\w.-]+ instead of the dotted-quad"],"exampleFix":"// before\nmatch = re.search(pattern, proxy_info)\nif not match.groups():\n    raise Exception(\"not match kuaidaili proxy info\")\n\n// after\nmatch = re.search(pattern, proxy_info)\nif match is None:\n    raise ValueError(f\"not match kuaidaili proxy info: {proxy_info!r}\")","handlingStrategy":"validation","validationCode":"KDL_RE = re.compile(r\"(\\d{1,3}\\.){3}\\d{1,3}:\\d{1,5},\\d+\")\n\nif not KDL_RE.search(proxy_info):\n    raise ValueError(f\"bad kdl proxy format: {proxy_info!r}\")\n# only now call parse_kuaidaili_proxy(proxy_info)","typeGuard":"def matches_kdl_pattern(s: str) -> bool:\n    return isinstance(s, str) and KDL_RE.search(s) is not None","tryCatchPattern":"try:\n    model = parse_kuaidaili_proxy(proxy_info)\nexcept (ValueError, AttributeError) as e:\n    # AttributeError: re.search returned None and the buggy guard dereferenced it\n    utils.logger.error(f\"kdl parse failed for {proxy_info!r}: {e!r}\")\n    raise IpGetError(\"unparseable kuaidaili proxy entry\") from e","preventionTips":["Pre-validate with the same regex before calling the parser","Upstream bug: `if not match.groups()` should be `if match is None` — patch it so None-match raises cleanly","Never feed proxies from a different provider into this parser"],"tags":["proxy","kuaidaili","regex","parsing","latent-bug"],"backgroundTag":null,"analyzedSha":"d6f7c5bb906b6dac40ddf343ef9e26438a3de092","analyzedAt":"2026-08-15T01:39:07.505Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}