「Throwbaleをcathcしない方が良いよ、って前に言われたことあるけどアレってソースある?」と言われまして。
※ 画像はイメージです
自分としては、どちらかというと「考えていったら自然とそう思えたので」という生き方をしており、確かにソースか〜探したことなかったなぁ。。。となり。即答できず。
「理屈はわかる」のと「毎度説明するのが面倒」は別物ですよね。
(寧ろ、折角PHPの本を書いたのだからそこで言及しても良かったかもな〜)
「話すの面倒くさいと説明のクオリティが毎回変わる」ので、あまり気持ちよくありません。
かといって、「毎回ちゃんと説明する」のは非常に骨も折れるので、それもやっぱり気持ちよくありません。
ということで、「Throwableってなに?Exceptionと何が違うの?調べてみました!」です。
- tl;dr
- いんとろ
- 前提: ポケモンキャッチ
- 改めて \Error とは
- なぜ Error(throwable) が必要だったのか?
- 捕捉・復帰ができない
- エラーハンドラとの兼ね合い
- finally, __destructとの兼ね合い
- RECOVERABLEであってもRECOVERするには扱いづらい
- Error が何か?を理解すると、catchしたくなくなる(はず)
- まとめ
・・・書いていたら思いの外長くなったので、tl;drをつけます😌
tl;dr
- 「Throwable(やError)をキャッチするべきではない」と考える
- Errorは「プログラミング的なミス」: 出荷されるコードで考慮されるべきではない(開発中の対処・解消が必須)
- ポケモンキャッチの問題: Throwableを直接扱うのは「結局なにを、どんな意図で拾いたいのか」をボヤけさせる
- しかし、これを述べているような公式的な文書やオーソリティのある見解を探したことがなかった
- 他の人は何と言ってるんだ・・?って気にしていなかったので、自分や小さなサークルで形成された「IMO」に過ぎないのか?
- 包括的に説明したい・それを「信用できる形」で行いたい
- ということで「ポケモンキャッチ」と「Throwable/Errorの性質、扱い」に関する文献を探したら見つかった
- ポケモンキャッチとかについて
- hirakさんの発表資料: PHPのエラーと例外再入門 / php-error-and-exception - Speaker Deck
- Pythonのチュートリアルでも言及されている: 8. エラーと例外 — Python 3.9.1rc1 ドキュメント
- ErrorやThorwableについて
- Error、Exception、エラーに関しておさらい: お前は PHP 7 における Fatal Error / Catchable Fatal Error / Error / ErrorException / Exception の違いを言えるか? - Qiita
- RFCを見ると「recoverbleな状況を適切にハンドリングしたい」というのがErrorの導入経緯だとわかる: PHP: rfc:engine_exceptions_for_php7
- 元々の名前が
EngineException
だったことも、現Errorの位置づけを感じ取りやすい
- 元々の名前が
- それらは「○○Exceptionと分けて考えて」というのを、Throwable についてのRFCから理解できる: PHP: rfc:throwable-interface
- trowski氏の記事。「ErrorやThrowableがどう扱われるべきか」が説明されている: https://trowski.com/2015/06/24/throwable-exceptions-and-errors-in-php
- 「信頼できるソース1つ出して」って言われたらコレが正解だな、という感じ
- Javaの「Error/Throwable」の説明も参考に: Error (Java Platform SE 7)
- ポケモンキャッチとかについて
これらの文献のうち、特に顕著な表現としてtrowski氏とThrowbaleのRFCの表現がわかりやすいです。これが「何かソースありますか?」に対する回答、ということで良いのではないか?
Error should be used to represent coding issues that require the attention of a programmer. Error objects thrown from the PHP engine fall into this category, as they generally result from coding errors such as providing a parameter of the wrong type to a function or a parse error in a file. Exception should be used for conditions that can be safely handled at runtime where another action can be taken and execution can continue.
Since Error objects should not be handled at runtime, catching Error objects should be uncommon. In general, Error objects should only be caught for logging, performing any necessary cleanup, and display an error message to the user.
https://trowski.com/2015/06/24/throwable-exceptions-and-errors-in-php7
また、ThrowableのRFCでも「キャッチすべきではない」と端的に説明されとります
catch (Error $e) and catch (Throwable $e) may be used to catch respectively Error objects or any Throwable (current or future) object. Users should generally be discouraged from catching Error objects except for logging or cleanup purposes as Error objects represent coding problems that should be fixed rather than runtime conditions that may be handled.
この辺りが、「ちょっと調べてみよ&ブログに残しておこ」と思ったきっかけに対する答えとなっております!
以下本編。
続きを読む