Loading page...Загружаем страницу...正在加载页面...
AtlasRepo

The Retry Keystroke Failed After Cancel: A Dead AbortSignal Retrospective

说明与用途

键盘用户可以取消流式请求,然后按 Retry,但 Retry 按钮仍然启用,而底层 AbortController 已被取消,导致无法启动新请求,UI 处于死状态。解决方案是在每次重试时创建新的 AbortController。

问题

Keyboard users can cancel a streaming request and then press Retry, but the retry button remains enabled while the underlying AbortController is already aborted, preventing a new request from starting and leaving the UI in a dead state.

结果

The bug was caused by reusing the same AbortController across attempts. The fix is to create a new AbortController for each retry, ensuring the controller is not already aborted when starting a new fetch.

工作流

  • 1. Focus composer and submit prompt with Enter.
  • 2. While status says generating, press Escape to cancel.
  • 3. Observe focus moves to Stop (or hidden).
  • 4. Tab to Retry and press Enter.
  • 5. Verify that a new attempt starts, live region announces retry, composer is enabled, and focus lands on Stop or composer.

证据

Retry is not a click handler glued onto a cancelled bubble. Retry is a transition that must create a new attempt.

来源

The first attempt had aborted, but Retry still held the same AbortController. signal.aborted was already true, so the next fetch never started.

来源

  • 记录日期: 2026-09-07T22:14:24.696Z