目次

エラー処理

例外

#

Dart コードでは、例外をスロー(発生)およびキャッチすることができます。例外は、予期せぬ事態が発生したことを示すエラーです。例外がキャッチされない場合、例外を発生させたIsolateは中断され、通常はIsolateとプログラムは終了します。

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

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

スロー

#

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

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

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

dart
throw 'Out of llamas!';

例外のスローは式であるため、`=>` 文だけでなく、式が許可される場所であればどこでも例外をスローできます。

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

キャッチ

#

例外をキャッチ(または捕捉)すると、例外の伝播が停止します(例外を再スローする場合を除く)。例外をキャッチすると、例外を処理する機会が得られます。

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');
}

前のコードに示されているように、`on` または `catch`、あるいはその両方を使用できます。例外型を指定する必要がある場合は `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` 節を使用します。`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(, );`)を使用して、ブール値の条件が 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`への引数は評価されません。