{"record":{"id":"a13a93030ef0f8e9","repo":"binary-husky/gpt_academic","slug":"error-a13a93","errorCode":null,"errorMessage":"程序终止。","messagePattern":"程序终止。","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"request_llms/bridge_qianfan.py","lineNumber":136,"sourceCode":"                raise ConnectionAbortedError(dec['error_msg'])  # 上下文太长导致 token 溢出\n            elif ('error_code' in dec):\n                raise RuntimeError(dec['error_msg'])\n\n\ndef predict_no_ui_long_connection(inputs:str, llm_kwargs:dict, history:list=[], sys_prompt:str=\"\",\n                                  observe_window:list=[], console_silence:bool=False):\n    \"\"\"\n        ⭐多线程方法\n        函数的说明请见 request_llms/bridge_all.py\n    \"\"\"\n    watch_dog_patience = 5\n    response = \"\"\n\n    for response in generate_from_baidu_qianfan(inputs, llm_kwargs, history, sys_prompt):\n        if len(observe_window) >= 1:\n            observe_window[0] = response\n        if len(observe_window) >= 2:\n            if (time.time()-observe_window[1]) > watch_dog_patience: raise RuntimeError(\"程序终止。\")\n    return response\n\ndef predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream = True, additional_fn=None):\n    \"\"\"\n        ⭐单线程方法\n        函数的说明请见 request_llms/bridge_all.py\n    \"\"\"\n    chatbot.append((inputs, \"\"))\n\n    if additional_fn is not None:\n        from core_functional import handle_core_functionality\n        inputs, history = handle_core_functionality(additional_fn, inputs, history, chatbot)\n\n    yield from update_ui(chatbot=chatbot, history=history)\n    # 开始接收回复\n    try:\n        response = f\"[Local Message] 等待{model_name}响应中 ...\"\n        for response in generate_from_baidu_qianfan(inputs, llm_kwargs, history, system_prompt):","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/request_llms/bridge_qianfan.py#L118-L154","documentation":"Watchdog RuntimeError('程序终止。' - program terminated) in bridge_qianfan.predict_no_ui_long_connection: observe_window[1] holds the caller's heartbeat and if it is not refreshed within watch_dog_patience (=5) seconds the consume loop aborts. This is the standard cooperative-cancellation contract used across all bridges in this project; with Qianfan's fast SSE frames it almost always means the feeder thread stopped, not a slow server.","triggerScenarios":"Caller thread that owns observe_window stopped updating the timestamp (user cancelled, UI closed, feeder thread crashed); exception in the consumer between yields leaving the dog unfed; debug breakpoint pausing the process >5s.","commonSituations":"User hits Stop during ERNIE Bot generation; plugin wraps predict_no_ui_long_connection without starting the feeder thread; Gradio session teardown.","solutions":["Treat as expected cancellation if the user stopped the job - clean up partial state and exit","Guarantee a feeder thread updates observe_window[1] = time.time() at least every few seconds while the result is still wanted","Raise watch_dog_patience if intentional slow consumption is expected","Catch RuntimeError and inspect the message before deciding to retry"],"exampleFix":"# caller contract\now = ['', time.time()]\ndef feeder():\n    while running:\n        ow[1] = time.time()\n        time.sleep(2)","handlingStrategy":"try-catch","validationCode":"import time\now[1] = time.time()\nassert len(observe_window) >= 2, 'watchdog contract: observe_window[1] must be a heartbeat timestamp'","typeGuard":null,"tryCatchPattern":"try:\n    result = predict_no_ui_long_connection(inputs, llm_kwargs, history, observe_window=ow)\nexcept RuntimeError as e:\n    if '程序终止' in str(e):\n        return ow[0]  # partial text; caller cancelled\n    raise","preventionTips":["Start the heartbeat feeder before the first generator call, not after","Centralize the feeder-thread helper across plugins so it is never omitted","Consider cancellation a normal control flow, not an error to log loudly"],"tags":["qianfan","watchdog","cancellation","concurrency","baidu"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}