{"record":{"id":"71c9f5db62cdb0b4","repo":"NaiboWang/EasySpider","slug":"dont-parse-timezone-format","errorCode":null,"errorMessage":"dont parse timezone format","messagePattern":"dont parse timezone format","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"warning","filePath":"Examples/Sample Tasks with Python/author_crawl.py","lineNumber":51,"sourceCode":"        return {\n            'symbol': symbol,\n            'offset': offset\n        }\n\n    @classmethod\n    def convert_timezone(cls, dt, timezone=\"+0\"):\n        \"\"\"默认是utc时间，需要\"\"\"\n        result = cls.parse_timezone(timezone)\n        symbol = result['symbol']\n\n        offset = result['offset']\n\n        if symbol == '+':\n            return dt + timedelta(hours=offset)\n        elif symbol == '-':\n            return dt - timedelta(hours=offset)\n        else:\n            raise Exception('dont parse timezone format')\n\n\ndef generate_timestamp():\n    current_GMT = time.gmtime()\n    # ts stores timestamp\n    ts = calendar.timegm(current_GMT)\n\n    current_time = datetime.utcnow()\n    convert_now = TimeUtil.convert_timezone(current_time, '+8')\n    print(\"current_time:    \" + str(convert_now))\n    return str(convert_now)\n\n\ndef main():\n    # result = os.popen('python ServiceWrapper_ExecuteStage.py 38')\n    # res = result.read()\n    # for line in res.splitlines():\n    #     print(\"\\n\\n\\n\\nfinename:\\n\\n\\n\\n\\n\", line)","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/NaiboWang/EasySpider/blob/191bd6d7547bb397e4c579dd2c70ae835be3f512/Examples/Sample Tasks with Python/author_crawl.py#L33-L69","documentation":"Raised by TimeUtil.convert_timezone in Examples/.../author_crawl.py:51 when the parsed timezone symbol is neither '+' nor '-'. In the shipped code this branch is effectively UNREACHABLE: parse_timezone uses the regex (?P<symbol>[+-])(?P<offset>\\d+) which only ever captures '+' or '-'. A genuinely malformed timezone string (e.g. 'UTC', '8', '') instead makes re.match return None, so result.groupdict() throws AttributeError before convert_timezone reaches the symbol check. Hitting THIS exact message implies parse_timezone was modified to emit a non +/- symbol.","triggerScenarios":"TimeUtil.convert_timezone(dt, timezone) calls cls.parse_timezone(timezone); if a future/modified parse_timezone returns {'symbol': <not +/->, ...}, the if/elif chain falls through to raise Exception('dont parse timezone format').","commonSituations":"The sample is copy-pasted and parse_timezone is edited to support named zones; or timezone comes from external config that bypasses the regex; or a monkeypatch returns a symbol the if-chain does not recognize. The far more common real-world failure from bad input is AttributeError: 'NoneType' object has no attribute 'groupdict', not this message.","solutions":["Validate the timezone string against ^[+-]\\d+$ before calling convert_timezone.","Fix parse_timezone to handle a no-match: if not result: raise ValueError(f'invalid timezone: {timezone!r}').","Replace the generic Exception with ValueError and cover the real failure (None match) instead of the dead else."],"exampleFix":"# before\nresult = re.match(r'(?P<symbol>[+-])(?P<offset>\\d+)', timezone)\nsymbol = result.groupdict()['symbol']  # AttributeError if no match\n\n# after\nresult = re.match(r'(?P<symbol>[+-])(?P<offset>\\d+)', timezone)\nif not result:\n    raise ValueError(f'invalid timezone format: {timezone!r}')\nsymbol = result.group('symbol')\noffset = int(result.group('offset'))","handlingStrategy":"validation","validationCode":"import re\nif not re.match(r'^[+-]\\d+$', timezone or ''):\n    raise ValueError(f'timezone must look like +8 / -5, got {timezone!r}')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pass user-supplied timezone strings straight into convert_timezone; validate shape first.","Prefer pytz/zoneinfo for real timezone handling instead of hand-rolled hour offsets.","Unit-test parse_timezone with '+8', '-5', '0', 'UTC', '' to lock in the contract."],"tags":["python","timezone","dead-code","validation","easyspider"],"backgroundTag":null,"analyzedSha":"191bd6d7547bb397e4c579dd2c70ae835be3f512","analyzedAt":"2026-08-13T03:11:17.041Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}