> つまり、プログラムが不整合状態になったとき、プログラムは全体として既に想定を満たさない状態で動いている可能性があり、その結果として発生する処理やデータも基本的に無意味である[6]。 その無意味な処理で無意味なデータを解釈して「復帰」しようとする行為も、当然無意味である。
https://blog.cardina1.red/2019/12/19/dont-fear-the-panic/#additional-topics--still-wondering
端的にはコレです
> * プログラムが完全に掌握しているはずのデータが誤っていれば、 panic せよ
> * プログラムのバグが原因なら、 panic せよ
> * 環境や外部データに問題があるなら Result を返すべし
> * エンドユーザに問題があるなら Result を返すべし
> * ありえないことが起きたなら panic せよ
たとえばですが、
「jsonファイルがフィールド a と b を持っている」
という想定があったとして、「a や b がなかったり余計な c があったりするファイルを読んだ」は「想定可能なエラー」なんですよ。この場合クラッシュすべきでない。
で、じゃあどういう場合にクラッシュすべきかというと、
「json ファイルがフィールド a と b を持っていてそれを読んだのに、返すオブジェクトで a の値を設定し忘れた」とかそういう「デシリアライザが仕様違反を犯している場合」です。
この場合「デシリアライザが『こういうデータを読みますよ』と (仕様で暗黙に) 表明したデータ以外を返す」というのは仕様外動作なので、そこから復帰しようとすべきでない。
私が言いたいのは
* I/O エラーは想定可能であり、常に復帰や適切なエラーハンドリングを試みるべき
* 逆に内部的な不整合や実装自体の仕様違反を原因とする問題に気付いたら、速やかに明示的なクラッシュをするべき
* バグは「エラー」ではない
* 不注意や人間のキャパを越えたエラー仕様で例外をキャッチし損ねてクラッシュするのは言語仕様が駄目
あたりです
「エラーが値である Rust ではメソッドチェーンや通常の関数でエラーからの復帰を書けるのに対して、例外が戻り値型と別の存在になっている言語では構文レベルで特殊な扱いが必要になる」というエラーハンドリングの言語由来の複雑性の違いを例示したかったやつです
これ <https://mastodon.cardina1.red/@lo48576/105634679893487496> のことを言ってるのなら、これはマジで単なる例で、 <https://mastodon.cardina1.red/@lo48576/105634688953669899> と対比しただけです (I/O エラーを問答無用で無視する実装が正しいかは別の問題)