3日坊主ITエンジニア > Blazor WebAssembly Tips (ASP.NET CORE6) > Blazor WebAssemblyのErrorBoundaryでキャッチできない例外がある(ASP.NET CORE 6)
Blazor WebAssemblyのErrorBoundaryでキャッチできない例外がある(ASP.NET CORE 6)
概要
この記事の内容は実際の挙動をもとにした推察になります。誤っている可能性があります。
Blazor WebAssemblyのページを<ErrorBoundary>のタグで括ると、ページ内で例外が発生した際にErrorBoundaryのOnErrorAsyncで例外をキャッチできるのですが、キャッチできないものがあります。
パターン1 非同期処理でのTaskCanceledException
ページ内のpublic async Taskの非同期メソッドの中でTaskCanceledExceptionが発生してもErrorBoundaryのOnErrorAsyncでキャッチされません。
たぶん、async Task自体のキャンセル扱いと取られてErrorBoundaryの処理対象外となっているのかもしれません。
実際に困るケースは、HttpClientの通信タイムアウトの時で、タイムアウトになるとTaskCanceledExceptionが発生します。
対策としては、HttpClientの処理をラップして、Try CatchでTaskCanceledExceptionをキャッチして、別の例外に置き換えてThrowします。
パターン2 別タスクで発生した例外
メソッドのなかで、Task.Runにより別タスクで処理を行い、その中で例外が発生した場合、ErrorBoundaryは例外をキャッチしません。
Task.Runの後にWait()を実行すれば、Wait実行時に例外が発生するので、この場合はErrorBoundaryで例外をキャッチします。
※別タスクで実行して投げっぱなしにするケースの場合に例外をキャッチしません。
パターン3 InputFileタグのOnChangeイベントから呼び出したメソッドで発生した例外
もうなぜだかさっぱりわかりません。
InputFileタグのOnChangeイベントから呼び出されたメソッドで発生した例外はことごとくErrorBoundaryでキャッチできません。
完全に推測ですが、InputFileタグのOnChangeから呼ばれたメソッドは完全に別タスク扱いになる(つまりパターン2と同じ状態になる)のではないかと思っています。
対策としては、メソッド内でTry Catchでエラーハンドリングして、メソッド内で適切に処理するしかなさそうです。
結論
そもそもErrorBoundaryで例外を一元処理する方針が間違っているのかもしれません。
例外は各メソッドでキャッチし、画面内の特定箇所やダイアログボックスでエラーがあった旨のメッセージを表示したほうがよいかもしれません。
なぜなら、Blazor WebAssemblyなどのいわゆるSPA系は昔のクライアントサーバシステムに似ているからです。
昔のクライアントサーバシステムは例外が発生すると、エラー画面に遷移させるのではなく、例外が発生した画面にエラーメッセージを表示するというスタイルで、SPAの場合もそのスタイルを踏襲したほうが自然なのかもしれません。