动态

详情 返回 返回

Flutter/Dart第13天:Dart錯誤處理 - 动态 详情

Dart官方文檔:https://dart.dev/language/error-handling

重要説明:本博客基於Dart官網文檔,但並不是簡單的對官網進行翻譯,在覆蓋核心功能情況下,我會根據個人研發經驗,加入自己的一些擴展問題和場景驗證。

異常

和Java一樣,Dart也可以拋出異常,也可以捕獲異常。Dart異常如果未被捕獲,容易導致進程掛起和導致程序退出。所以,我們在編寫Dart程序時,需要特別關注異常。

和Java不同的是,Dart中的異常全部都是未檢測異常。如果一個方法沒有申明任何類型的異常,那麼我們就無需捕獲該方法的異常。

Dart提供了ExceptionError兩種異常的基礎類型,同時內置了其他一些它們的子類。我們也可以定義我們自己的異常類型,Dart可以把任何非空的對象當作異常拋出,且這些對象類型不一定是ExceptionError類型的子類(和Java有很大區別)。

throw拋出異常

Dart可以把任務非空對象當作異常拋出,但建議拋出的異常為Exception或者Error的子類,下面是幾個代碼樣例:

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

throw 'Out of llamas!';

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

catch捕獲異常

捕獲異常,一般有種目的:一是為了阻止異常繼續傳播,二是我們期望重新拋出異常。

捕獲異常的語法有幾種:

  • on 異常類型 catch(異常對象)
  • catch(異常對象)
  • catch(異常對象, 異常堆棧)

捕獲異常後,我們可以進行一些處理。我們可以根據異常類型,捕獲多個異常。異常語句中若未定義異常類型,則捕獲所有異常,如下代碼樣例:

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // `OutOfLlamasException`類型的異常
  buyMoreLlamas();
} on Exception catch (e) {
  // `Exception`類型的異常
  print('Unknown exception: $e');
} catch (e) {
  // 其他的所有的異常
  print('Something really unknown: $e');
}

異常堆棧類型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重新拋出異常

如下代碼樣例,當捕獲到異常之後,可以通過rethrow重新拋出異常:

void misbehave() {
  try {
    dynamic foo = true;
    print(foo++); // 製造異常
  } catch (e) {
    print('misbehave() partially handled ${e.runtimeType}.');
    rethrow; // 重新拋出異常
  }
}

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

finally子句

當我們不論是否有異常發生,都行執行某個邏輯時,我們可用使用finally子句。當發生異常時,首先執行catch子句進行捕獲,若未被捕獲或者重新拋出異常,那麼這個異常會在執行完fianlly之後被拋出。

try {
  breedMoreLlamas();
} finally {
  // 不論是否有異常發生,均會執行本邏輯
  cleanLlamaStalls();
}

try {
  breedMoreLlamas();
} catch (e) {
  // 首先:捕獲異常
  print('Error: $e');
} finally {
  // 然後:執行本邏輯
  cleanLlamaStalls();
}

斷言

在應用的開發階段,通過結果為false的斷言語句(如:assert(<condition>, <optionalMessage>);語句)來阻斷程序執行。幾種斷言語句的代碼樣例:

// `text`不能為null
assert(text != null);

// `number`必須小於100
assert(number < 100);

// `urlString`必須以`https`開頭
assert(urlString.startsWith('https'), 'URL ($urlString) should start with "https".');

斷言失敗(表達式結果為false)時,拋出AssertionError類型(Error類型的子類)的異常。

斷言在以下場景下會生效:

  • Flutter應用程序在debug模式(開發階段,開啓了斷言)。
  • 類似於webdev等開發工具,默認開啓了斷言。
  • 類似於dart rundart compile js等工具,且通過命令行增加了--enable-asserts開啓斷言參數。

而在生產階段,斷言相關代碼被忽略,因此斷言會失效(不會執行)。


我的本博客原地址:https://ntopic.cn/p/2023101401


Add a new 评论

Some HTML is okay.