binary-husky/gpt_academic · warning · RuntimeError
用户取消了程序。
Error message
用户取消了程序。
What it means
Watchdog inside the OpenAI-compatible streaming loop: observe_window[1] holds a timestamp maintained by the UI; if it is not refreshed within watch_dog_patience (5 s), the code raises RuntimeError('用户取消了程序。'). It detects user cancellation (stop button / closed page) via the stale observation window — network slowness does not trigger it because the check runs only when new chunks arrive.
Source
Thrown at request_llms/oai_std_model_template.py:257
f"API异常,请检测终端输出。可能的原因是:{finish_reason}"
)
if chunk:
try:
if finish_reason == "stop":
if not console_silence:
print(f"[response] {result}")
break
result += response_text
if reasoning:
reasoning_buffer += reasoning_content
if observe_window is not None:
# 观测窗,把已经获取的数据显示出去
if len(observe_window) >= 1:
observe_window[0] += response_text
# 看门狗,如果超过期限没有喂狗,则终止
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解析不合常规")
if reasoning:
paragraphs = ''.join([f'<p style="margin: 1.25em 0;">{line}</p>' for line in reasoning_buffer.split('\n')])
return f'''<div class="reasoning_process" >{paragraphs}</div>\n\n''' + result
return result
def predict(
inputs,
llm_kwargs,
plugin_kwargs,
chatbot,
history=[],
system_prompt="",View on GitHub (pinned to d6bde0fa54)
Solutions
- Intended behavior on user stop — nothing to fix if cancellation was deliberate.
- Custom callers: refresh observe_window[1] each iteration or pass a single-element window to disable the watchdog.
- If stop is unwanted, keep the chat tab active and avoid pressing 'Stop' during generation.
Example fix
# before
for chunk in predict_no_ui_long_connection(inputs, llm_kwargs, observe_window=obs):
pass
# after
for chunk in predict_no_ui_long_connection(inputs, llm_kwargs, observe_window=obs):
obs[1] = time.time() Defensive patterns
Strategy: validation
Validate before calling
# disable watchdog for programmatic use: single-element window observe_window = ['']
Try / catch
try:
for chunk in predict_no_ui_long_connection(...):
obs[1] = time.time()
except RuntimeError as e:
if str(e) == '用户取消了程序。':
return partial_result() # graceful cancel, not a failure Prevention
- Feed observe_window[1] every iteration in custom consumers.
- Distinguish cancellation exceptions from real errors in handlers.
- Pass a 1-element window when cancellation is not wanted.
When it happens
Trigger: During streaming, the front end stops updating observe_window[1] = time.time() for more than 5 seconds AND a new chunk arrives — user hit stop, switched gradio tab, or the caller stopped feeding the window.
Common situations: User cancels a long generation; gradio page refreshed mid-answer; custom plugins that pass a two-slot observe_window but never refresh slot 1 while iterating.
Related errors
AI-assisted analysis of binary-husky/gpt_academic@d6bde0fa54 (2026-08-14).
Data as JSON: /api/errors/c3a07b2ed1e60c8b.
Report an issue: GitHub.