リリース・改善中
Dart ガイド · 5/6
この章は現在、英語でのみ提供しています。
Dart signals failures with exceptions and handles them with try/catch. There are no checked exceptions, and an uncaught exception propagates upward. This chapter covers throwing and catching exceptions, assert, and writing and running tests with package:test and dart test.
Dart's core libraries divide problems into two families.
| Kind | Meaning | Examples |
|---|---|---|
Exception | An expected failure the caller should handle | FormatException, IOException, TimeoutException |
Error | A programming bug, usually fixed rather than caught | RangeError, TypeError, StateError, ArgumentError |
Malformed input or a dropped connection is an Exception for the caller to handle. Indexing past the end of a list is an Error: fix the cause instead of hiding it. throw accepts any object, but by convention you throw only Exception or Error types.
class InsufficientFundsException implements Exception {
InsufficientFundsException(this.balance, this.amount);
final int balance;
final int amount;
@override
String toString() => 'Insufficient funds: balance $balance, requested $amount';
}
class Account {
int _balance = 0;
int get balance => _balance;
void deposit(int amount) {
if (amount <= 0) {
throw ArgumentError.value(amount, 'amount', 'must be positive');
}
_balance += amount;
}
void withdraw(int amount) {
if (amount > _balance) {
throw InsufficientFundsException(_balance, amount);
}
_balance -= amount;
}
}Use on Type to catch a specific exception, and catch (e, s) to receive the exception object and the stack trace. A finally block always runs, whether or not an exception occurred, so it is the place for cleanup. To log an exception and pass it on, use rethrow, which preserves the original stack trace.
int parseAge(String input) {
try {
final age = int.parse(input);
if (age < 0) throw FormatException('negative age', input);
return age;
} on FormatException catch (e) {
print('Format error: ${e.message}');
return 0;
} catch (e, stackTrace) {
print('Unexpected error: $e');
print(stackTrace);
rethrow;
} finally {
print('parseAge done');
}
}
void main() {
print(parseAge('42')); // 42
print(parseAge('abc')); // prints a format error, then 0
final account = Account()..deposit(100);
try {
account.withdraw(500);
} on InsufficientFundsException catch (e) {
print(e); // Insufficient funds: balance 100, requested 500
}
}The same syntax works in async functions. When an awaited Future completes with an error, the exception is thrown at the await, so you simply wrap it in try/catch.
Future<String> loadConfig() async {
try {
return await readRemoteConfig();
} on TimeoutException {
return '{}'; // fall back to defaults on timeout
}
}TimeoutException is from dart:async; readRemoteConfig is any async loader.
assert(condition, message) throws an AssertionError when the condition is false. Use it to document assumptions you want checked during development. Asserts are disabled by default and enabled when you run with dart run --enable-asserts, when you run tests with dart test, and in Flutter debug mode. In production builds they are not even evaluated, so never use them for checks that must always happen, such as validating user input.
class Percent {
Percent(this.value) : assert(value >= 0 && value <= 100, 'must be 0 to 100');
final int value;
}Dart's standard testing library is package:test. Projects created with dart create already include it; otherwise add it with dart pub add --dev test. Put test files in the test/ directory and end their names with _test.dart.
// test/account_test.dart
import 'package:test/test.dart';
import 'package:bank/account.dart';
void main() {
group('Account', () {
late Account account;
setUp(() {
account = Account()..deposit(100);
});
test('deposit increases the balance', () {
account.deposit(50);
expect(account.balance, equals(150));
});
test('withdrawing more than the balance throws', () {
expect(
() => account.withdraw(500),
throwsA(isA<InsufficientFundsException>()),
);
});
test('non-positive deposit throws ArgumentError', () {
expect(() => account.deposit(0), throwsArgumentError);
});
});
}The basic form is expect(actual, matcher); a plain value is compared with equals. Common matchers include isTrue, isNull, contains, hasLength, isA<T>(), throwsA and throwsArgumentError. setUp and tearDown run around each test, setUpAll and tearDownAll once per group. A test body may be async; the runner waits for its Future.
dart test # every test under test/
dart test test/account_test.dart # a single file
dart test --name "deposit" # only tests whose names match
dart test --reporter expanded # one line per test
dart test --coverage=coverage # collect coverage dataA failing test shows expected and actual values and the location. In CI, running dart analyze, dart format --set-exit-if-changed . and dart test in sequence gives you a solid baseline of quality checks. Flutter projects use flutter test, which builds on the same package:test API.
Dart separates expected failures (Exception) from bugs (Error). Catch specific exceptions with on, receive the stack trace with catch (e, s), clean up in finally, and pass exceptions on with rethrow. Use assert for assumptions checked only during development, write tests with test, group and expect from package:test, and run them with dart test.
コメント 0件
ログイン · ログインするとコメントできます。
最初のコメントを書いてみましょう。