{"record":{"id":"c3a07b2ed1e60c8b","repo":"binary-husky/gpt_academic","slug":"error-c3a07b","errorCode":null,"errorMessage":"用户取消了程序。","messagePattern":"用户取消了程序。","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"warning","filePath":"request_llms/oai_std_model_template.py","lineNumber":257,"sourceCode":"                    f\"API异常,请检测终端输出。可能的原因是:{finish_reason}\"\n                )\n            if chunk:\n                try:\n                    if finish_reason == \"stop\":\n                        if not console_silence:\n                            print(f\"[response] {result}\")\n                        break\n                    result += response_text\n                    if reasoning:\n                        reasoning_buffer += reasoning_content\n                    if observe_window is not None:\n                        # 观测窗，把已经获取的数据显示出去\n                        if len(observe_window) >= 1:\n                            observe_window[0] += response_text\n                        # 看门狗，如果超过期限没有喂狗，则终止\n                        if len(observe_window) >= 2:\n                            if (time.time() - observe_window[1]) > watch_dog_patience:\n                                raise RuntimeError(\"用户取消了程序。\")\n                except Exception as e:\n                    chunk = get_full_error(chunk, stream_response)\n                    chunk_decoded = chunk.decode()\n                    error_msg = chunk_decoded\n                    logger.error(error_msg)\n                    raise RuntimeError(\"Json解析不合常规\")\n        if reasoning:\n            paragraphs = ''.join([f'<p style=\"margin: 1.25em 0;\">{line}</p>' for line in reasoning_buffer.split('\\n')])\n            return f'''<div class=\"reasoning_process\" >{paragraphs}</div>\\n\\n''' + result\n        return result\n\n    def predict(\n        inputs,\n        llm_kwargs,\n        plugin_kwargs,\n        chatbot,\n        history=[],\n        system_prompt=\"\",","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/request_llms/oai_std_model_template.py#L239-L275","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nfor chunk in predict_no_ui_long_connection(inputs, llm_kwargs, observe_window=obs):\n    pass\n\n# after\nfor chunk in predict_no_ui_long_connection(inputs, llm_kwargs, observe_window=obs):\n    obs[1] = time.time()","handlingStrategy":"validation","validationCode":"# disable watchdog for programmatic use: single-element window\nobserve_window = ['']","typeGuard":null,"tryCatchPattern":"try:\n    for chunk in predict_no_ui_long_connection(...):\n        obs[1] = time.time()\nexcept RuntimeError as e:\n    if str(e) == '用户取消了程序。':\n        return partial_result()  # graceful cancel, not a failure","preventionTips":["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."],"tags":["watchdog","cancellation","streaming","ui"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}