Dart - 錯誤處理
錯誤處理
Dart 提供了兩個主要的異常類型:
Exception
:表示程序中的邏輯錯誤或其他可預期的問題。開發者可以使用這個類型來表示可以處理或恢復的錯誤。Error
:表示程序中的嚴重問題,通常是程序無法恢復的錯誤,如內存溢出、無效的狀態等。 或是開發者也可以自定義異常來更靈活處理錯誤。
info
錯誤處理在各種程式語言都很重要!
- 管理錯誤狀態:通過捕獲異常,開發者可以根據具體情況做出相應的處理,如提示用戶、重試操作、記錄日誌等。
- 避免程式碼中斷執行:通過適當的異常處理, 可以防止程序因未處理的異常而崩潰,從而提高程序的健壯性和穩定性。
Catch 捕獲異常
Dart 捕獲異常是使用 try
配合 on
跟 catch
:
try {
breedMoreLlamas();
} on OutOfLlamasException {
buyMoreLlamas();
}
也可以使用多個 catch
來處理不同類型的異常:
try {
breedMoreLlamas();
} on OutOfLlamasException {
// 處理特定的 OutOfLlamasException 異常
buyMoreLlamas();
} on Exception catch (e) {
// 處理所有其他的 Exception 類型的異常
print('Unknown exception: $e');
} catch (e) {
// 處理所有其他未被捕獲的異常
print('Something really unknown: $e');
}
info
on
跟 catch
的差異
on
:用於處理特定類型的異常。適合需要區分不同異常類型並進行相應處理的情況。catch
:用於捕獲所有異常,並可以獲取異常對象和堆棧跟蹤 (Stack Trace)。適合處理通用異常和需要詳細異常信息的情況。 從概念尚可以知道on
跟catch
負責的事情類似但本質不一樣:on
就像售票員檢查入場券一樣,只讓有有效入場券的人進入。這意味著當特定類型的異常發生時,相應的處理程序將被觸發。catch
就像救護人員在事故現場一樣。無論異常的類型是什麼,catch
都會將它捕獲並進行相應的處理,無需對異常進行額外的分類。
Throw 拋出異常
以下是拋出異常的範例:
// example1
throw FormatException('Expected at least 1 section');
// example2
throw 'Out of llamas!';
// example3
void distanceTo(Point other) => throw UnimplementedError();
也可以透過 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}.');
}
}
解釋一下上面 rethrow
做了什麼:
misbehave()
函式開始執行。- 在
misbehave()
函式中,嘗試對一個 bool 變數進行自增操作,這是不合法的。 - 由於自增操作不合法,導致運行時錯誤。
- 運行時錯誤被
catch
塊捕獲,程式執行進入catch
塊。 - 在
catch
塊中,打印一條消息,表明misbehave()
函式部分處理了這個異常。 - 在
catch
塊中,使用rethrow
關鍵字重新抛出這個異常。 - 異常被重新抛出後,它會繼續向上傳播到
main()
函式。 - 異常被
main()
函式中的catch
塊捕獲。 - 在
main()
函式的catch
塊中,打印一條消息,表明main()
函式處理了這個異常。
Finally
finally
用於確保某些程式碼無論異常是否被拋出都會執行。
這意味著即使在 try
區塊中的程式碼引發異常,finally
中的程式碼仍然會被執行。
如果沒有 catch
子句去捕獲異常,則 finally
執行完畢後,該異常會繼續向外傳遞。
try {
breedMoreLlamas();
} finally {
// Always clean up, even if an exception is thrown.
cleanLlamaStalls();
}