{"record":{"id":"67e7f167ff059c36","repo":"NaiboWang/EasySpider","slug":"dont-parse-timezone-format-67e7f1","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/desc_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/desc_crawl.py#L33-L69","documentation":"Identical to error 2 but in Examples/Sample Tasks with Python/desc_crawl.py:51. Same TimeUtil.convert_timezone / parse_timezone code duplicated across sample tasks. The 'dont parse timezone format' else branch is unreachable given the shipped regex; the observable failure for bad input is an AttributeError from None.groupdict() in parse_timezone.","triggerScenarios":"TimeUtil.convert_timezone(dt, timezone) where a modified parse_timezone returns a symbol other than '+' or '-'; or, in practice, parse_timezone crashes first on a non-matching timezone string.","commonSituations":"Copy-pasted sample task scripts drift from each other; desc_crawl.py carries the same latent bug as author_crawl.py. Bad timezone from config or CLI triggers the AttributeError variant.","solutions":["Apply the same fix as error 2 to desc_crawl.py (and any other copy): validate timezone shape and guard the None regex result.","Extract TimeUtil into a shared module and import it in both sample tasks to kill the duplication.","Add a unit test for parse_timezone covering valid and invalid inputs."],"exampleFix":"# before (desc_crawl.py)\nresult = re.match(r'(?P<symbol>[+-])(?P<offset>\\d+)', timezone)\nsymbol = result.groupdict()['symbol']\n\n# after\nif not re.match(r'^[+-]\\d+$', timezone or ''):\n    raise ValueError(f'invalid timezone: {timezone!r}')","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":["Deduplicate TimeUtil into one shared module imported by all sample tasks.","Validate timezone at the entry point (config load) not deep inside the utility."],"tags":["python","timezone","dead-code","duplication","easyspider"],"backgroundTag":null,"analyzedSha":"191bd6d7547bb397e4c579dd2c70ae835be3f512","analyzedAt":"2026-08-13T03:11:17.041Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}