dart-fix-runtime-errors

dart-fix-runtime-errors

熱門

使用 get_runtime_errors 和 lsp 取得活躍的堆疊追蹤,定位錯誤行,套用修復,並透過 hot_reload 驗證解決。

392星標
25分支
更新於 2026/7/10
SKILL.md
readonlyread-only
name
dart-fix-runtime-errors
description

Uses get_runtime_errors and lsp to fetch an active stack trace, locate the failing line, apply a fix, and verify resolution via hot_reload.

解決 Dart 靜態分析錯誤

目錄

核心概念與指南

型別系統與健全性

強制執行 Dart 的健全型別系統,以防止執行時期無效狀態。

  • 方法覆寫: 維持健全的回傳型別(covariant)與參數型別(contravariant)。除非明確標記 covariant 關鍵字,否則切勿在子類別中縮小參數型別。
  • 泛型與集合: 為泛型類別(例如 List<T>Map<K, V>)加入明確的型別註解。切勿將 List<dynamic> 指派給有型別的列表(例如 List<Cat>)。
  • 向下轉型: 避免從 dynamic 隱含向下轉型。必要時使用明確轉型(例如 as List<Cat>),但需確保底層執行時期型別相符,以防止 TypeError 例外。
  • 嚴格轉型:analysis_options.yamlanalyzer: language: 下啟用 strict-casts: true,以強制明確轉型並在編譯時期捕捉隱含向下轉型錯誤。

空值安全

透過正確管理變數初始化與可空性,消除與空值安全相關的靜態錯誤。

  • 修飾詞: 對可空型別使用 ?,對空值斷言使用 !,對不可為空的具名參數使用 required
  • 延遲初始化: 對保證在使用前初始化的非可空變數使用 late 關鍵字。特別適用於 Dart 的控制流程分析無法明確證明初始化的頂層或實例變數。
  • 萬用字元: 使用 _ 萬用字元變數(Dart 3.7+)表示非綁定的區域變數或參數,以避免未使用變數的警告。

錯誤處理

區分可復原的例外與不可復原的錯誤。

  • 捕捉: 對可復原的失敗捕捉 Exception 子型別。
  • 錯誤: 切勿明確捕捉 Error 或其子型別(例如 TypeErrorArgumentError)。錯誤表示程式設計錯誤,必須修復而非捕捉。透過啟用 avoid_catching_errors 檢查規則來強制執行。
  • 重新拋出:catch 區塊內使用 rethrow 傳播例外,同時保留其原始堆疊追蹤。

工作流程

工作流程:靜態分析解析

使用此順序性工作流程來識別、修復並驗證 Dart 專案中的靜態分析錯誤。複製檢查清單以追蹤進度。

任務進度:

  • [ ] 1. 執行靜態分析器。
  • [ ] 2. 套用自動修復。
  • [ ] 3. 手動解決其餘錯誤。
  • [ ] 4. 驗證修復(回饋迴圈)。

1. 執行靜態分析器
執行 Dart 分析器以識別目標目錄或檔案中的所有靜態錯誤。

dart analyze . --fatal-infos

2. 套用自動修復
使用 dart fix 工具自動解決標準的 lint 與分析問題。

# 預覽變更
dart fix --dry-run
# 套用變更
dart fix --apply

3. 手動解決其餘錯誤
檢視其餘的分析器輸出,並根據錯誤型別套用條件邏輯:

  • 如果錯誤是空值安全問題(例如「無法在可空接收器上存取屬性」):
    • 確認變數邏輯上是否可為 null。
    • 如果是,使用可選鏈接(?.)或提供預設值(??)。
    • 如果否,且初始化已在其他地方保證,則將宣告標記為 late
  • 如果錯誤是型別不符(例如「引數型別 'List<dynamic>' 無法指派...」):
    • 追蹤變數的初始化。
    • 在實例化中加入明確的泛型型別註解(例如使用 <int>[] 而非 [])。
  • 如果錯誤是無效覆寫(例如「參數型別與被覆寫的方法不符」):
    • 放寬參數型別以符合父類別,或者
    • 如果領域邏輯需要縮小型別,則在參數中加入 covariant 關鍵字。

4. 驗證修復(回饋迴圈)
執行驗證器。檢視錯誤。修復。

dart analyze .
dart test
  • 如果 dart analyze 回報錯誤: 返回步驟 3。
  • 如果 dart testTypeError 失敗: 您引入了無效的明確轉型(as T)或存取了未初始化的 late 變數。找出執行時期失敗並修正型別階層或初始化順序。

範例

範例:修正動態列表指派

輸入(靜態分析失敗):

void printInts(List<int> a) => print(a);

void main() {
  final list = []; // 推斷為 List<dynamic>
  list.add(1);
  list.add(2);
  printInts(list); // 錯誤:List<dynamic> 無法指派給 List<int>
}

輸出(靜態分析通過):

void printInts(List<int> a) => print(a);

void main() {
  final list = <int>[]; // 明確指定型別
  list.add(1);
  list.add(2);
  printInts(list);
}

範例:修正方法覆寫(反變性)

輸入(靜態分析失敗):

class Animal {
  void chase(Animal a) {}
}

class Cat extends Animal {
  @override
  void chase(Mouse a) {} // 錯誤:縮小參數型別
}

輸出(靜態分析通過):

class Animal {
  void chase(Animal a) {}
}

class Cat extends Animal {
  @override
  void chase(covariant Mouse a) {} // 明確標記 covariant
}

範例:使用 late 修正空值安全

輸入(靜態分析失敗):

class Thermometer {
  String temperature; // 錯誤:非可空實例欄位必須初始化

  void read() {
    temperature = '20C';
  }
}

輸出(靜態分析通過):

class Thermometer {
  late String temperature; // 將初始化檢查延遲到執行時期

  void read() {
    temperature = '20C';
  }
}