Skip to content

feat: time out stalled requests, stop collapsing 5xx into FAILED - #10

Merged
tmlksu merged 1 commit into
mainfrom
feat/timeouts-and-5xx
Sep 1, 2026
Merged

tmlksu merged 1 commit into
mainfrom
feat/timeouts-and-5xx

Conversation

@tmlksu

@tmlksu tmlksu commented Sep 1, 2026

Copy link
Copy Markdown
Owner

非公開の運用リポジトリ側のメモに「移行後も残る弱点 (上流に起票する)」として書かれたまま、起票されていなかった 2 件。どちらもトンネル越しの共有で刺さる話で、まさにその構成が当事者。

1. どのリクエストにも期限が無かった

トンネルやプロキシが応答を返さなくなると fetch が解決せず、Files アプリが無限に待つ。ChromeOS 側に FSP のリクエストを中断する手段は無いので、ユーザにできることが何も無い状態になる。

メタデータ (PROPFIND) を 30 秒、本体の読み出しを 120 秒で打ち切るようにした。読み出し側を長く取っているのは、遅い回線を弾かないため。

期限は呼び出しごとではなく試行ごとに張り直す。 AccessAuth は失効を検知すると最大 90 秒のログインを挟んで内部で再試行するので、ログイン待ちを跨いで同じ期限を使い回すと再試行が必ず中断される。DavClient は signal と予算の両方を渡し、素の fetch を渡された場合は signal が効き、内部で再試行する auth 実装は予算から張り直す。

この張り直しが無いと落ちる回帰テストを入れてある(外すと実際に落ちることを確認済み)。

2. 5xx が FAILED に潰れていた

502/503/504 に分岐が無く、拡張のバグや設定ミスと同じ FAILED になっていた。「トンネルが落ちている」「認証が違う」「拡張が壊れている」がユーザから区別できない。

5xx とタイムアウトを IO に写像した。501 は INVALID_OPERATION のまま — 「そのメソッドを実装していない」であって経路の障害ではないので、5xx の分岐より先に評価している。

toProviderError を errors.js に切り出した。background.js は chrome を import するので node から読めず、この写像はこれまで一度もテストできていなかった。今回変えるのがまさにそこなので先に出した。

ついでに直したハーネスのバグ

compat.sh は DAV_SHARE_PATH の既定値を mktemp -d にしていたが、これは 0700。Apache はコンテナ内で別 uid で動くのでツリーを辿れず、既定の呼び出し方だと 7 台中 2 台が 403 で落ちる。make-tree.sh で chmod -R a+rX するようにした。実際に踏んで気づいた。

確認

  • ユニットテスト 90 → 108 件
  • 実サーバ 7 構成すべて回帰なし:
rclone      207  206  合格 (66 件)
apache      207  206  合格 (66 件)
dufs        207  206  合格 (66 件)
hacdias     207  206  合格 (66 件)
dufs-auth   207  206  合格 (66 件)
nextcloud   207  -    合格 (149 件)
nginx       405  206  対象外 (想定どおり)

🤖 Generated with Claude Code

Both weaknesses were written down in the private deployment repo's notes as
things to raise upstream, and never were. They matter most to a share behind a
tunnel, which is the setup those notes describe.

No request had a deadline. When a tunnel or proxy stops answering, fetch never
settles and the Files app waits forever — ChromeOS gives the user no way to
cancel an FSP request. Metadata now gets 30s and body reads 120s, the longer
budget so a slow link isn't cut off.

The deadline is renewed per attempt rather than per call. AccessAuth retries
internally after a login that can take 90 seconds, so a single deadline
spanning the login would guarantee the retry aborts. DavClient passes both a
signal and the budget: the signal covers a plain fetch, and an auth wrapper
that retries re-arms from the budget.

Separately, 502/503/504 had no branch in the error mapping and fell through to
FAILED, alongside genuine bugs and misconfiguration. They now map to IO, as do
timeouts. 501 keeps INVALID_OPERATION — "method not implemented" is not a
broken path.

toProviderError moves to errors.js so it can be tested at all; it was the only
logic in background.js, which imports chrome and cannot be loaded under node.

Also chmod the test tree in make-tree.sh. compat.sh defaults DAV_SHARE_PATH to
mktemp -d, which is 0700, and Apache runs as another uid inside its container —
so the default invocation failed with 403 on two of the seven servers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@tmlksu
tmlksu merged commit b345b68 into main Sep 1, 2026
3 checks passed
@tmlksu
tmlksu deleted the feat/timeouts-and-5xx branch September 1, 2026 23:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant