binary-husky/gpt_academic · error · RuntimeError
用户取消了程序。
Error message
用户取消了程序。
What it means
RuntimeError raised by the watchdog in bridge_ollama.predict_no_ui_long_connection. The caller passes an observe_window list whose second element holds the last 'feed' timestamp; if the consuming thread does not refresh observe_window[1] within watch_dog_patience seconds, the generation loop assumes the user pressed stop and aborts. Despite the message text ('user cancelled the program'), it fires on any watchdog timeout, not only an explicit cancel.
Source
Thrown at request_llms/bridge_ollama.py:110
except requests.exceptions.ConnectionError:
chunk = next(stream_response) # 失败了,重试一次?再失败就没办法了。
chunk_decoded, chunkjson, is_last_chunk = decode_chunk(chunk)
if chunk:
try:
if is_last_chunk:
# 判定为数据流的结束,gpt_replying_buffer也写完了
logger.info(f'[response] {result}')
break
result += chunkjson['message']["content"]
if not console_silence: print(chunkjson['message']["content"], end='')
if observe_window is not None:
# 观测窗,把已经获取的数据显示出去
if len(observe_window) >= 1:
observe_window[0] += chunkjson['message']["content"]
# 看门狗,如果超过期限没有喂狗,则终止
if len(observe_window) >= 2:
if (time.time()-observe_window[1]) > watch_dog_patience:
raise RuntimeError("用户取消了程序。")
except Exception as e:
chunk = get_full_error(chunk, stream_response)
chunk_decoded = chunk.decode()
error_msg = chunk_decoded
logger.error(error_msg)
raise RuntimeError("Json解析不合常规")
return result
def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream = True, additional_fn=None):
"""
发送至chatGPT,流式获取输出。
用于基础的对话功能。
inputs 是本次问询的输入
top_p, temperature是chatGPT的内部调优参数
history 是之前的对话列表(注意无论是inputs还是history,内容太长了都会触发token数量溢出的错误)
chatbot 为WebUI中显示的对话列表,修改它,然后yield出去,可以直接修改对话界面内容
additional_fn代表点击的哪个按钮,按钮见functional.pyView on GitHub (pinned to d6bde0fa54)
Solutions
- If the user truly cancelled, no fix is needed - the error is the intended stop signal
- Otherwise, make the consumer thread update observe_window[1] = time.time() every iteration while it still wants output
- Increase watch_dog_patience if the local Ollama server legitimately stalls longer than the limit
- Catch RuntimeError around the call and check the message to distinguish cancellation from other failures
Example fix
// before
for resp in predict_no_ui_long_connection(..., observe_window=ow):
pass # never feed the dog
// after
while True:
ow[1] = time.time()
try:
resp = next(it)
except StopIteration:
break Defensive patterns
Strategy: try-catch
Validate before calling
import time
# contract check before calling
assert len(observe_window) >= 2 and isinstance(observe_window[1], float), \
'observe_window must be [buffer, heartbeat_timestamp]' Try / catch
try:
result = predict_no_ui_long_connection(inputs, llm_kwargs, history, observe_window=ow)
except RuntimeError as e:
if str(e) == '用户取消了程序。':
return ow[0] # partial output, user cancelled
raise Prevention
- Always spawn a feeder thread that refreshes observe_window[1] every 1-2 seconds while output is still wanted
- Treat this exact message as the cancellation signal, not as a provider failure
- Never retry automatically on cancellation - check user intent first
When it happens
Trigger: Calling predict_no_ui_long_connection with observe_window=[buffer, timestamp] and never updating observe_window[1] while streaming; user clicking Stop in the WebUI which stops feeding the dog; a slow Ollama server whose chunks exceed the patience window.
Common situations: Plugin code that reuses the observe_window pattern but forgets to refresh the timestamp each loop; long generations on a heavily loaded local Ollama instance; genuine user cancellation via the Gradio UI.
Related errors
AI-assisted analysis of binary-husky/gpt_academic@d6bde0fa54 (2026-08-14).
Data as JSON: /api/errors/5ba436821800e540.
Report an issue: GitHub.