錯誤處理
異常
#你的 Dart 程式碼可以丟擲和捕獲異常。異常是表示發生了意外情況的錯誤。如果異常未被捕獲,丟擲異常的隔離區 (isolate) 將被掛起,通常該隔離區及其程式也會終止。
與 Java 不同,Dart 的所有異常都是非檢查異常。方法不會宣告它們可能丟擲哪些異常,並且你無需捕獲任何異常。
Dart 提供了 Exception 和 Error 型別,以及許多預定義的子型別。當然,你可以定義自己的異常。然而,Dart 程式可以丟擲任何非空物件作為異常,而不僅僅是 Exception 和 Error 物件。
丟擲
#這是一個丟擲(或引發)異常的例子
throw FormatException('Expected at least 1 section');你也可以丟擲任意物件
throw 'Out of llamas!';因為丟擲異常是一個表示式,所以你可以在 => 語句以及任何允許表示式的地方丟擲異常
void distanceTo(Point other) => throw UnimplementedError();捕獲
#捕獲異常可以阻止異常傳播(除非你重新丟擲異常)。捕獲異常讓你有機會處理它
try {
breedMoreLlamas();
} on OutOfLlamasException {
buyMoreLlamas();
}要處理可能丟擲多種型別異常的程式碼,可以指定多個 catch 子句。第一個匹配丟擲物件型別的 catch 子句會處理該異常。如果 catch 子句沒有指定型別,該子句可以處理任何型別的丟擲物件
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() 指定一個或兩個引數。第一個是被丟擲的異常,第二個是堆疊跟蹤(一個 StackTrace 物件)。
try {
// ···
} on Exception catch (e) {
print('Exception details:\n $e');
} catch (e, s) {
print('Exception details:\n $e');
print('Stack trace:\n $s');
}要部分處理異常,同時允許其繼續傳播,請使用 rethrow 關鍵字。
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 子句執行後傳播。
try {
breedMoreLlamas();
} finally {
// Always clean up, even if an exception is thrown.
cleanLlamaStalls();
}finally 子句在任何匹配的 catch 子句之後執行
try {
breedMoreLlamas();
} catch (e) {
print('Error: $e'); // Handle the exception first.
} finally {
cleanLlamaStalls(); // Then clean up.
}要了解更多資訊,請查閱核心庫異常文件。
斷言
#在開發期間,使用 assert 語句 — assert(<condition>, <optionalMessage>); — 如果布林條件為假,則中斷正常執行。
// 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 的第二個引數(可選地帶上尾隨逗號)
assert(
urlString.startsWith('https'),
'URL ($urlString) should start with "https".',
);assert 的第一個引數可以是任何解析為布林值的表示式。如果表示式的值為 true,斷言成功並繼續執行。如果為 false,斷言失敗並丟擲異常(一個 AssertionError)。
斷言到底何時起作用?這取決於你使用的工具和框架
- Flutter 在除錯模式下啟用斷言。
- 僅用於開發的工具,例如
webdev serve,通常預設啟用斷言。 - 一些工具,例如
dart run和dart compile js,透過命令列標誌--enable-asserts支援斷言。
在生產程式碼中,斷言會被忽略,並且不會評估 assert 的引數。