{"record":{"id":"4d72091315a10e47","repo":"binary-husky/gpt_academic","slug":"error-4d7209","errorCode":null,"errorMessage":"程序终止。","messagePattern":"程序终止。","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"request_llms/bridge_google_gemini.py","lineNumber":42,"sourceCode":"    genai = GoogleChatInit(llm_kwargs)\n    watch_dog_patience = 5  # 看门狗的耐心, 设置5秒即可\n    gpt_replying_buffer = ''\n    stream_response = genai.generate_chat(inputs, llm_kwargs, history, sys_prompt)\n    for response in stream_response:\n        results = response.decode()\n        match = re.search(r'\"text\":\\s*\"((?:[^\"\\\\]|\\\\.)*)\"', results, flags=re.DOTALL)\n        error_match = re.search(r'\\\"message\\\":\\s*\\\"(.*?)\\\"', results, flags=re.DOTALL)\n        if match:\n            try:\n                paraphrase = json.loads('{\"text\": \"%s\"}' % match.group(1))\n            except:\n                raise ValueError(f\"解析GEMINI消息出错。\")\n            buffer = paraphrase['text']\n            gpt_replying_buffer += buffer\n            if len(observe_window) >= 1:\n                observe_window[0] = gpt_replying_buffer\n            if len(observe_window) >= 2:\n                if (time.time() - observe_window[1]) > watch_dog_patience: raise RuntimeError(\"程序终止。\")\n        if error_match:\n            raise RuntimeError(f'{gpt_replying_buffer} 对话错误')\n    return gpt_replying_buffer\n\ndef make_media_input(inputs, image_paths):\n    image_base64_array = []\n    for image_path in image_paths:\n        path = os.path.abspath(image_path)\n        inputs = inputs + f'<br/><br/><div align=\"center\"><img src=\"file={path}\"></div>'\n        base64 = encode_image(path)\n        image_base64_array.append(base64)\n    return inputs, image_base64_array\n\ndef predict(inputs:str, llm_kwargs:dict, plugin_kwargs:dict, chatbot:ChatBotWithCookies,\n            history:list=[], system_prompt:str='', stream:bool=True, additional_fn:str=None):\n\n    from .bridge_all import model_info\n","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/request_llms/bridge_google_gemini.py#L24-L60","documentation":"Raised inside the Gemini streaming loop (predict_no_ui_long_connection) by a watchdog: if the time stored in observe_window[1] is more than watch_dog_patience seconds (5s) behind time.time(), the stream is considered stalled and the generator aborts with RuntimeError('程序终止。'). It is a client-side liveness check on the SSE stream, not a Gemini API error.","triggerScenarios":"Calling predict_no_ui_long_connection with an observe_window list of length >= 2 where observe_window[1] was set to a start timestamp, and no successfully decoded '\"text\":' chunk arrives within 5 seconds (slow network, proxy stall, or the API stopped sending deltas).","commonSituations":"Flaky proxy/VPN to generativelanguage.googleapis.com, Gemini rate-limiting or hanging the connection, large prompt causing long silent thinking time, or the caller forgetting to refresh observe_window[1] between chunks.","solutions":["Check network/proxy reachability to the Gemini endpoint (curl a minimal streaming request) and retry once.","Raise watch_dog_patience (e.g. to 30s) or have the caller update observe_window[1] on each yield so only true stalls trip the dog.","If the stream legitimately produces no text for long periods (safety refusal), handle the empty-buffer path at the end of the loop instead of relying on the watchdog.","Upgrade/patch the bridge to use the official google-generativeai SDK instead of regex-scraping raw SSE bytes."],"exampleFix":"// before\nwatch_dog_patience = 5\nif (time.time() - observe_window[1]) > watch_dog_patience: raise RuntimeError(\"程序终止。\")\n\n# after\nwatch_dog_patience = 30\nif (time.time() - observe_window[1]) > watch_dog_patience:\n    raise RuntimeError(\"Gemini stream stalled for >30s; check proxy/network.\")","handlingStrategy":"retry","validationCode":"import time\nstart = time.time()\n# caller refreshes window[1] each iteration\nwindow = ['', time.time()]\ntry:\n    out = predict_no_ui_long_connection(..., observe_window=window)\nexcept RuntimeError as e:\n    if '程序终止' in str(e) and time.time()-start < 120:\n        window[1] = time.time(); retry = True  # one retry with refreshed watchdog","typeGuard":null,"tryCatchPattern":"try:\n    result = predict_no_ui_long_connection(...)\nexcept RuntimeError as e:\n    if '程序终止' in str(e):\n        # watchdog stall: refresh observe_window[1] and retry once\n        ...","preventionTips":["Pass a 2+ element observe_window and refresh window[1] on every poll","Keep watch_dog_patience >= worst-case Gemini silence (30s)","Test proxy reachability to generativelanguage.googleapis.com before long jobs"],"tags":["gemini","streaming","watchdog","timeout","network"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}