Vuex でのエラーの扱いについての個人的な考え

最新の dex.fm — Development at Mercari US で、Redux でのエラーの扱いについての言及があって、自分は Vuex (Redux インスパイアな Vue の状態管理ライブラリ)でどうやっていたっけな、というのを文章で簡単に書いておきます。あくまで個人の考えです。

予め、Vuex の Action は、Redux の Action とは異なることを書いておきます。Vuex の Action は、純粋な State の変更を行う前の非同期や副作用が伴う処理を指し、純粋な State の変更は Mutation でおこなっています。Redux での非同期処理の扱いについて書かれた ReduxでのMiddleware不要論 - Qiita の記事の ActionDispatcher に近いものです。

Vuex でのエラーの扱いに関しては

コンポーネント内で閉じるか否かによる

この一言に尽きます。

Vuex のドキュメントでは、ひとつのコンポーネントに閉じている State について、以下のように述べています。

Vuex を使うということは、全ての状態を Vuex の中に置くべき、というわけではありません。多くの状態を Vuex に置くことで、状態の変更がさらに明示的、デバッグ可能になりますが、ときにはコードを冗長でまわりくどいものにします。状態の一部がひとつのコンポーネントだけに属している場合は、それをローカルの状態として残しておくとよいでしょう。あなたは、トレードオフを考慮した上で、あなたのアプリの開発ニーズに合った決定をすべきです。

自分もこの考え方に賛成で、Vuex に限らず Flux アークテキチャを適用した場合、ひとつのコンポーネントに閉じている State は無理に Store で管理しなくてもよいのでは、と考えています( 複数のコンポーネントに跨った State になるときに Store へ移せばよい)。

エラーに関しても、State と同様に考えます。厳密に単方向のデータフローを守り、エラーが発生した際に Action を Dispatch するか、Mutation を Commit すれば、上記のドキュメントの引用と同様の利点がありますが、エラーが画面に表示されるまでの処理がまわりくどいものになる場合もあります。

Vuex の Action でエラーが発生したことを Action を Dispatch したコンポーネントだけが知ればよい場合は、コンポーネント内でエラーハンドリングをおこなえばよいのではないでしょうか。Vuex の Action Dispatch は Promise オブジェクトを返すインターフェイスになっているので、以下のように catch メソッドでエラーをハンドリングできます。

this.$store.dispatch('fetchSomeData').catch(() => {
  // alert を出す or コンポーネントのステートを変更する
});

Action でのエラー発生を複数のコンポーネントに跨って扱う、State を変更する場合は、Action 内でエラーハンドリングして、さらに Action を Dispatch するか、Mutation を Commit する形になるでしょう。その後、変更された State を適切なコンポーネントで扱います。

おわり