メインコンテンツにスキップ

エラー処理

例外

#

Dart コードは例外をスローしてキャッチできます。例外とは、予期しないことが発生したことを示すエラーです。例外がキャッチされない場合、例外を発生させたアイソレートは中断され、通常はそのアイソレートとプログラムが終了します。

Java とは異なり、Dart の例外はすべてチェックされない例外です。メソッドはスローする可能性のある例外を宣言せず、例外をキャッチする必要もありません。

Dart は Exception および Error 型、および多数の定義済みサブタイプを提供します。もちろん、独自の例外を定義することもできます。ただし、Dart プログラムは、例外およびエラーオブジェクトだけでなく、null でない任意のオブジェクトを例外としてスローできます。

Throw (スロー)

#

例外をスロー(または*発生*)する例を次に示します。

dart
throw FormatException('Expected at least 1 section');

任意のオブジェクトをスローすることもできます。

dart
throw 'Out of llamas!';

例外をスローすることは式であるため、=> ステートメント内や、式が許可される他の場所で例外をスローできます。

dart
void distanceTo(Point other) => throw UnimplementedError();

Catch (キャッチ)

#

例外をキャッチ(または*捕捉*)すると、例外が伝播するのを停止します(例外を再スローしない限り)。例外をキャッチすると、それを処理する機会が得られます。

dart
try {
  breedMoreLlamas();
} on OutOfLlamasException {
  buyMoreLlamas();
}

複数の種類の例外をスローする可能性のあるコードを処理するには、複数の catch 句を指定できます。スローされたオブジェクトの型と一致する最初の catch 句が例外を処理します。catch 句が型を指定しない場合、その句は任意の型のスローされたオブジェクトを処理できます。

dart
try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // A specific exception
  buyMoreLlamas();
} on Exception catch (e) {
  // Anything else that is an exception
  print('Unknown exception: $e');
} catch (e) {
  // No specified type, handles all
  print('Something really unknown: $e');
}

前のコードが示すように、oncatch、またはその両方を使用できます。例外の型を指定する必要がある場合は on を使用します。例外ハンドラーが例外オブジェクトを必要とする場合は catch を使用します。

catch() に 1 つまたは 2 つのパラメータを指定できます。最初のパラメータはスローされた例外、2 番目のパラメータはスタックトレース(StackTrace オブジェクト)です。

dart
try {
  // ···
} on Exception catch (e) {
  print('Exception details:\n $e');
} catch (e, s) {
  print('Exception details:\n $e');
  print('Stack trace:\n $s');
}

例外を部分的に処理し、伝播を許可するには、rethrow キーワードを使用します。

dart
void misbehave() {
  try {
    dynamic foo = true;
    print(foo++); // Runtime error
  } catch (e) {
    print('misbehave() partially handled ${e.runtimeType}.');
    rethrow; // Allow callers to see the exception.
  }
}

void main() {
  try {
    misbehave();
  } catch (e) {
    print('main() finished handling ${e.runtimeType}.');
  }
}

Finally (ファイナリー)

#

例外がスローされたかどうかにかかわらず、一部のコードを実行することを保証するには、finally 句を使用します。catch 句が例外と一致しない場合、finally 句が実行された後に例外が伝播されます。

dart
try {
  breedMoreLlamas();
} finally {
  // Always clean up, even if an exception is thrown.
  cleanLlamaStalls();
}

finally 句は、一致する catch 句の後に実行されます。

dart
try {
  breedMoreLlamas();
} catch (e) {
  print('Error: $e'); // Handle the exception first.
} finally {
  cleanLlamaStalls(); // Then clean up.
}

詳細については、コアライブラリの例外ドキュメントを参照してください。

Assert (アサート)

#

開発中は、assert ステートメント— assert(<condition>, <optionalMessage>); —を使用して、ブール条件が false の場合に通常の実行を中断します。

dart
// Make sure the variable has a non-null value.
assert(text != null);

// Make sure the value is less than 100.
assert(number < 100);

// Make sure this is an https URL.
assert(urlString.startsWith('https'));

アサーションにメッセージを添付するには、assert の 2 番目の引数に文字列を追加します(オプションで末尾のカンマを使用)。

dart
assert(
  urlString.startsWith('https'),
  'URL ($urlString) should start with "https".',
);

assert の最初の引数は、ブール値に解決される任意の式にすることができます。式の値が true の場合、アサーションは成功し、実行が継続されます。 false の場合、アサーションは失敗し、例外(AssertionError)がスローされます。

アサーションはいつ機能しますか?それは、使用しているツールとフレームワークによって異なります。

  • Flutter は、デバッグモードでアサーションを有効にします。
  • webdev serve のような開発専用ツールは、通常、デフォルトでアサーションを有効にします。
  • dart rundart compile js のような一部のツールは、コマンドラインフラグ --enable-asserts を介してアサーションをサポートしています。

本番コードでは、アサーションは無視され、assert の引数は評価されません。