{"record":{"id":"cf7027e59fd5731d","repo":"binary-husky/gpt_academic","slug":"txt","errorCode":null,"errorMessage":"无法下载资源{txt}，请检查。","messagePattern":"无法下载资源(.+?)，请检查。","errorType":"exception","errorClass":"ConnectionRefusedError","httpStatus":null,"severity":"error","filePath":"crazy_functions/crazy_utils.py","lineNumber":567,"sourceCode":"    返回值\n    - success: 布尔值，表示函数是否成功执行。\n    - file_manifest: 文件路径列表，里面包含以指定类型为后缀名的所有文件的绝对路径。\n    - project_folder: 字符串，表示文件所在的文件夹路径。如果是网络上的文件，就是临时文件夹的路径。\n    该函数详细注释已添加，请确认是否满足您的需要。\n    \"\"\"\n    import glob, os\n\n    success = True\n    if txt.startswith('http'):\n        # 网络的远程文件\n        import requests\n        from toolbox import get_conf\n        from toolbox import get_log_folder, gen_time_str\n        proxies = get_conf('proxies')\n        try:\n            r = requests.get(txt, proxies=proxies)\n        except:\n            raise ConnectionRefusedError(f\"无法下载资源{txt}，请检查。\")\n        path = os.path.join(get_log_folder(plugin_name='web_download'), gen_time_str()+type)\n        with open(path, 'wb+') as f: f.write(r.content)\n        project_folder = get_log_folder(plugin_name='web_download')\n        file_manifest = [path]\n    elif txt.endswith(type):\n        # 直接给定文件\n        file_manifest = [txt]\n        project_folder = os.path.dirname(txt)\n    elif os.path.exists(txt):\n        # 本地路径，递归搜索\n        project_folder = txt\n        file_manifest = [f for f in glob.glob(f'{project_folder}/**/*'+type, recursive=True)]\n        if len(file_manifest) == 0:\n            success = False\n    else:\n        project_folder = None\n        file_manifest = []\n        success = False","sourceCodeStart":549,"sourceCodeEnd":585,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/crazy_functions/crazy_utils.py#L549-L585","documentation":"Raised as ConnectionRefusedError when a plugin receives an http(s) URL and requests.get(txt, proxies=proxies) throws any exception. The bare except swallows the real cause (DNS failure, TLS error, timeout, bad proxy), so the original network error is lost. It comes from the file-download branch of the wildcard-path resolution helper in crazy_utils (txt.startswith('http')).","triggerScenarios":"Calling a plugin with txt='https://...' where the host is unreachable, DNS fails, the URL scheme is mistyped (e.g. 'http:/example.com'), or get_conf('proxies') returns a proxy that refuses connections. Note requests.get is called with no timeout, so a hung connection can also hang the plugin indefinitely before any exception.","commonSituations":"Misconfigured USE_PROXY/proxies in shared_utils/config (proxy pointing at a dead local port like 7890), corporate networks blocking the target, typo'd URL, or offline environments. The bare except makes the real reason invisible, which is the main pain point.","solutions":["Check connectivity to the URL from the same machine: curl -x \"$proxy\" <url> using the proxy from get_conf('proxies')","Verify the proxies setting in config (set USE_PROXY=False or fix the proxy address/port)","Reproduce the real error in a REPL: import requests; requests.get(txt, proxies=get_conf('proxies'), timeout=30) to see the underlying exception","Patch the bare except to a targeted one and include the cause, e.g. except requests.RequestException as e: raise ConnectionRefusedError(f'无法下载资源{txt}: {e}')","Add a timeout=... argument to requests.get so stalls fail fast instead of hanging"],"exampleFix":"// before\ntry:\n    r = requests.get(txt, proxies=proxies)\nexcept:\n    raise ConnectionRefusedError(f\"无法下载资源{txt}，请检查。\")\n\n// after\ntry:\n    r = requests.get(txt, proxies=proxies, timeout=60)\nexcept Exception as e:\n    raise ConnectionRefusedError(f\"无法下载资源{txt}：{e!r}\") from e","handlingStrategy":"retry","validationCode":"import requests\nfrom toolbox import get_conf\n\ndef url_reachable(txt, timeout=10):\n    try:\n        proxies = get_conf('proxies')\n        requests.head(txt, proxies=proxies, timeout=timeout, allow_redirects=True)\n        return True\n    except requests.RequestException:\n        return False","typeGuard":"def is_downloadable_url(txt: str) -> bool:\n    return txt.startswith('http') and '://' in txt","tryCatchPattern":"try:\n    files = resolve_wildcard_path(txt, type)\nexcept ConnectionRefusedError as e:\n    # probe for the real cause the bare except hid\n    import requests\n    try:\n        requests.head(txt, proxies=get_conf('proxies'), timeout=10)\n    except requests.RequestException as cause:\n        log.error(f'download failed, root cause: {cause!r}')\n    raise","preventionTips":["Validate URL reachability with a short HEAD request before invoking the plugin","Keep proxies/USE_PROXY config accurate for the deployment network","Always pass a timeout to requests calls; the current call has none and can hang","Never rely on the message text for diagnosis — the bare except discards the cause, so log your own probe"],"tags":["network","download","proxy","exception-chaining","python"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}