環境
- PHP 8.1
バグと例外の階層構造
前提として、バグと例外の違いは以下の通りです。
- どちらも、期待する処理に失敗することを意味するが、
- バグは、何度試しても失敗する
- 成功したり失敗したりする
- PHPにおける例外(Exception)は、Throwableクラスを基底としている
https://www.php.net/manual/ja/class.error.php - Throwableクラスは以下のような階層構造になっており、以下のように大別できる
- ErrorおよびExceptionのうちのRuntimeException以外はバグ系統
Exceptionと名称がついていても、実際はバグに分類できる「バグを表す例外」が存在する - RuntimeExceptionは純粋な例外
- ErrorおよびExceptionのうちのRuntimeException以外はバグ系統
Throwable
Error
ArithmeticError
DivisionByZeroError
AssertionError
CompileError
ParseError
FiberError
TypeError
ArgumentCountError
UnhandledMatchError
ValueError
Exception
ClosedGeneratorException
DOMException
ErrorException
IntlException
JsonException
LogicException
BadFunctionCallException
BadMethodCallException
DomainException
InvalidArgumentException
LengthException
OutOfRangeException
PharException
ReflectionException
RuntimeException
OutOfBoundsException
OverflowException
PDOException
RangeException
UnderflowException
UnexpectedValueException
SodiumException
対処方法の違い
- バグ系統のErrorおよびExceptionのうちのRuntimeException以外はtry-catchでキャッチすべきでない
- InvalidArgumentExceptionなど
- これらの本質は、構文エラーやロジックのエラーなど、本来コード修正をするべきプログラムエラーであるため(catchしたとしても、問題を先延ばしにしているだけに過ぎない)
- RuntimeExceptionは、プログラム自体は正しいが、以下のようなケースで外部の要因により生じる例外のため、それに応じた例外処理を実装しておくべきである
- データベースへの接続に失敗(PDOException)
- 数回リトライするなど。
- ユーザーから不正なインプットを受け取った (UnexpectedValueException)
- 422のバリデーションエラーをブラウザ側に返却し、キャッチしてエラーページを表示する等
- データベースへの接続に失敗(PDOException)
まとめ
いかがでしたでしょうか。本記事では、PHPにおけるバグと例外の違いを区別するために必要な知識について紹介しました。特に、phpのThrowableを基底とする階層構造は、少し複雑になっており、それぞれの違いを理解して実装する必要があるため、その方法について詳細に解説しています。