Skip to content

fix(frontend): propagate quest write errors to callers - #591

Open
RyuKiyo66 wants to merge 1 commit into
hackdays-io:mainfrom
RyuKiyo66:fix/522-quest-write-error-propagation
Open

RyuKiyo66 wants to merge 1 commit into
hackdays-io:mainfrom
RyuKiyo66:fix/522-quest-write-error-propagation

Conversation

@RyuKiyo66

Copy link
Copy Markdown

Closes #522

概要

Quest の書き込み系フックが catch でエラーを握りつぶしていたため、wallet で署名を拒否しても、コントラクトが revert しても、RPC がタイムアウトしても、UI は「承認しました」等の成功 toast を表示していました。オペレータから見ると「承認したはずなのに Kanban が動かない」状態になります。

ルート側(app/routes/$treeId_.quest.$questId.tsx)は既に

try { await approve(...); toast.success("承認しました"); await refetch(); }
catch (err) { toast.error("承認に失敗しました"); }

と正しく書かれていました。フックが例外を飲み込んで undefined を resolve していたため、この catch に到達できなかったのが原因です。

変更内容

1. 5つの書き込みフックから catch を削除

  • useSubmitQuestCompletion
  • useWithdrawQuestSubmission
  • useRejectQuestSubmission
  • useApproveQuest
  • useCancelQuest

finally { setIsLoading(false) } は残しているので、ローディング状態の解除は従来どおりです。呼び出し側は変更していません(既に正しい形のため)。

2. 早期 return を throw に変更(2つ目の silent success)

if (!hatsQuestModuleAddress || !wallet) return;   // ← これも「成功」として resolve される

このガードも catch と同じ問題を起こします。ボタン自体がワークスペース解決後にしか描画されないので、ここに落ちるのは状態ではなくバグです。共通ヘルパー requireQuestWriteContext に切り出し、throw するようにしました。戻り値で型が narrow されるため、各フック内の wallet / moduleAddress の扱いは従来と同じです。

3. テスト追加

requireQuestWriteContext の 3 ケースを useHatsQuestModule.test.ts に追加しました(アドレス欠落 / wallet 欠落 / 正常系)。

フック本体のレンダリングを伴うテストは @testing-library/react が必要ですが、現状 frontend の vitest は environment: "node" で純粋関数のみを対象にしています。ツールチェーンを増やさない方針(CLAUDE.md)に従い、ロジックを純粋関数に切り出す形でカバーしました。React 側のテスト基盤を入れる方針であれば、別 PR でフック単位のテストも追加できます。

変更していない箇所

useCreateQuest の catch はそのままです。こちらは { questIds, requested, error } を返してバッチの部分成功を呼び出し元に伝える設計で、呼び出し側($treeId_.$hatId_.$address_.quest.new.tsx)も created < count を見て「◯件作成しました(残り◯件は失敗)」と出し分けています。

動作確認

  • pnpm frontend test(40 passed)
  • pnpm frontend typecheck
  • pnpm biome:check
  • Sepolia: 承認権限のないアカウントで「承認」→ エラー toast が出る
  • Sepolia: wallet で署名を reject → エラー toast が出て Kanban が動かない
  • Sepolia: 正常系(承認 / 却下 / 取り下げ / キャンセル / 完了申請)が従来どおり成功する

follow-up の提案

Issue の Requirements にある「他のフックにも同様のパターンがないか確認」の結果です。同じ握りつぶしが以下に残っています。スコープが広がるため本 PR には含めていませんが、別 Issue を立てて対応してよければ起票します。

ファイル 該当行
hooks/useScheduledDistributor.ts L306, L332, L357, L463
hooks/useSplitsCreator.ts L71, L104, L135, L183
hooks/useHats.ts L107, L136, L181, L282, L347, L382, L417, L452, L487, L513, L548, L611, L644, L700
hooks/useFractionToken.ts 複数
hooks/useThanksToken.ts L374, L410

ただし呼び出し側が catch を持っているとは限らないので、フックだけ直すと無音の失敗が未ハンドル例外に変わります。フック修正とルート側の toast 対応はセットで進めるのが安全だと思います。

@vercel

vercel Bot commented Sep 16, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the Code for Japan Team on Vercel.

A member of the Team first needs to authorize it.

This branch has not been deployed

No deployments
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.

fix(frontend): quest write hooks show success toast on failure

1 participant