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

  1. Intended behavior on user stop — nothing to fix if cancellation was deliberate.
  2. Custom callers: refresh observe_window[1] each iteration or pass a single-element window to disable the watchdog.
  3. 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

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.