🚨
[Dart] Exceptionはcatchしていいが、Errorはコードのバグなので極力catchしてはいけない
DartにおけるError型とException型の使い分け
-
Error
- プログラムの問題
- コードの修正が必要であり、プログラムは強制終了した方が良い。
- try ~ catchで補足しない方が良い。
- 例
- ArgumentError
- AssertionError
- AsyncError
- NoSuchMethodError
- OutOfMemoryError
- StackOverflowError
- StateError
- TypeError
- プログラムの問題
-
Exception
- 実行時の問題
- コード側であらかじめ予期することが難しい。
- try ~ catchで制御した方が良い。
- catchしないとisolateが保留となり、そのisolateは終了する
- abstract + interface型として実装されている
- 独自のExceptionクラスを定義する場合は、implementする
- 例
- FormatException
- IOException
- TimeoutException
- DeferredLoadException
- IsolateSpawnException
- NullRejectionException
- OSError
- 実行時の問題
-
参考資料
Error class
Exception class
ExceptionのHandlingの実装例
try {
breedMoreLlamas();
} on OutOfLlamasException {
// 特定の種類のExceptionをcatch
buyMoreLlamas();
} on Exception catch (exception) {
// 全てに種類のExceptionをcatch
print('Unknown exception: $exception');
} catch (e, stackTrace) {
// errorも含めて全てcatch
// eはObject型
print('Something really unknown: $e');
print('Stack trace:\n $stackTrace');
} finally {
print('finally');
}
ExceptionのHandlingのプラクティス
Error handling(Effective Dart)
AVOID catches without on clauses.
ExceptionやErrorをcatchするときはon句を使って種類を制限する。
全てcatchするとErrorを握りつぶしてしまうため。
DON’T discard errors from catches without on clauses.
on句無しでのcatchを利用した場合、errorを必ず出力する。
errorは握り潰さない。
DO throw objects that implement Error only for programmatic errors.
Errorはコードにバグがあることを表すクラスなので、コードの修正が必要な場合のみErrorオブジェクトをthrowする。
普通にアプリケーション開発しているときにError throwすることはなさそう。
パッケージの開発する時とか。
DON’T explicitly catch Error or types that implement it.
今までと同じこと言ってる。
Errorはcatchしない、なぜならバグだから。
プログラムが終了するのが適切。
DO use rethrow to rethrow a caught exception.
catchした後に、再度Exceptionを発生させる場合はrethrowを使おう
try {
somethingRisky();
} catch (e) {
if (!canHandle(e)) rethrow;
handle(e);
}
Exceptionは伝播する
画像引用:https://www.cresc.co.jp/tech/java/Google_Dart2/language/exceptions/exceptions.html
Discussion