dart-fix-runtime-errors

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Resolving Dart Static Analysis Errors

解决Dart静态分析错误

Contents

目录

Core Concepts & Guidelines

核心概念与指南

Type System & Soundness

类型系统与健全性

Enforce Dart's sound type system to prevent runtime invalid states.
  • Method Overrides: Maintain sound return types (covariant) and parameter types (contravariant). Never tighten a parameter type in a subclass unless explicitly marked with the
    covariant
    keyword.
  • Generics & Collections: Add explicit type annotations to generic classes (e.g.,
    List<T>
    ,
    Map<K, V>
    ). Never assign a
    List<dynamic>
    to a typed list (e.g.,
    List<Cat>
    ).
  • Downcasting: Avoid implicit downcasts from
    dynamic
    . Use explicit casts (e.g.,
    as List<Cat>
    ) when necessary, but ensure the underlying runtime type matches to prevent
    TypeError
    exceptions.
  • Strict Casts: Enable
    strict-casts: true
    in
    analysis_options.yaml
    under
    analyzer: language:
    to force explicit casting and catch implicit downcast errors at compile time.
严格遵循Dart的健全类型系统,以防止运行时出现无效状态。
  • 方法重写: 保持健全的返回类型(协变)和参数类型(逆变)。除非显式使用
    covariant
    关键字标记,否则绝不要在子类中缩小参数类型。
  • 泛型与集合: 为泛型类添加显式类型注解(如
    List<T>
    Map<K, V>
    )。绝不要将
    List<dynamic>
    赋值给类型化列表(如
    List<Cat>
    )。
  • 向下转型: 避免从
    dynamic
    进行隐式向下转型。必要时使用显式转型(如
    as List<Cat>
    ),但要确保底层运行时类型匹配,以防止
    TypeError
    异常。
  • 严格转型:
    analysis_options.yaml
    analyzer: language:
    下启用
    strict-casts: true
    ,强制使用显式转型,并在编译时捕获隐式向下转型错误。

Null Safety

空安全

Eliminate static errors related to null safety by correctly managing variable initialization and nullability.
  • Modifiers: Apply
    ?
    for nullable types,
    !
    for null assertions, and
    required
    for named parameters that cannot be null.
  • Late Initialization: Use the
    late
    keyword for non-nullable variables guaranteed to be initialized before use. Apply this specifically to top-level or instance variables where Dart's control flow analysis cannot definitively prove initialization.
  • Wildcards: Use the
    _
    wildcard variable (Dart 3.7+) for non-binding local variables or parameters to avoid unused variable warnings.
通过正确管理变量初始化和可空性,消除与空安全相关的静态错误。
  • 修饰符: 对可空类型使用
    ?
    ,对空断言使用
    !
    ,对不能为空的命名参数使用
    required
  • 延迟初始化: 对保证在使用前会被初始化的非空变量使用
    late
    关键字。该关键字专门适用于Dart控制流分析无法明确证明已初始化的顶级变量或实例变量。
  • 通配符: 对非绑定局部变量或参数使用
    _
    通配符变量(Dart 3.7+),以避免未使用变量警告。

Error Handling

错误处理

Distinguish between recoverable exceptions and unrecoverable errors.
  • Catching: Catch
    Exception
    subtypes for recoverable failures.
  • Errors: Never explicitly catch
    Error
    or its subtypes (e.g.,
    TypeError
    ,
    ArgumentError
    ). Errors indicate programming bugs that must be fixed, not caught. Enforce this by enabling the
    avoid_catching_errors
    linter rule.
  • Rethrowing: Use
    rethrow
    inside a
    catch
    block to propagate an exception while preserving its original stack trace.
区分可恢复异常和不可恢复错误。
  • 捕获: 捕获
    Exception
    子类以处理可恢复故障。
  • 错误: 绝不要显式捕获
    Error
    或其子类(如
    TypeError
    ArgumentError
    )。错误表明必须修复的编程漏洞,而非捕获处理。通过启用
    avoid_catching_errors
    linter规则来强制执行这一点。
  • 重新抛出:
    catch
    块内使用
    rethrow
    来传播异常,同时保留其原始堆栈跟踪。

Workflows

工作流程

Workflow: Static Analysis Resolution

工作流程:静态分析错误解决

Use this sequential workflow to identify, fix, and verify static analysis errors in a Dart project. Copy the checklist to track your progress.
Task Progress:
  • 1. Run static analyzer.
  • 2. Apply automated fixes.
  • 3. Resolve remaining errors manually.
  • 4. Verify fixes (Feedback Loop).
1. Run static analyzer Execute the Dart analyzer to identify all static errors in the target directory or file.
bash
dart analyze . --fatal-infos
2. Apply automated fixes Use the
dart fix
tool to automatically resolve standard linting and analysis issues.
bash
undefined
使用此顺序工作流程识别、修复和验证Dart项目中的静态分析错误。复制检查清单以跟踪进度。
任务进度:
  • 1. 运行静态分析器。
  • 2. 应用自动修复。
  • 3. 手动解决剩余错误。
  • 4. 验证修复(反馈循环)。
1. 运行静态分析器 执行Dart分析器以识别目标目录或文件中的所有静态错误。
bash
dart analyze . --fatal-infos
2. 应用自动修复 使用
dart fix
工具自动解决标准 lint 和分析问题。
bash
undefined

Preview changes

预览更改

dart fix --dry-run
dart fix --dry-run

Apply changes

应用更改

dart fix --apply

**3. Resolve remaining errors manually**
Review the remaining analyzer output and apply conditional logic based on the error type:

*   **If the error is a Null Safety issue (e.g., "Property cannot be accessed on a nullable receiver"):**
    *   Verify if the variable can logically be null.
    *   If yes, use optional chaining (`?.`) or provide a fallback (`??`).
    *   If no, and initialization is guaranteed elsewhere, mark the declaration with `late`.
*   **If the error is a Type Mismatch (e.g., "The argument type 'List<dynamic>' can't be assigned..."):**
    *   Trace the variable's initialization.
    *   Add explicit generic type annotations to the instantiation (e.g., `<int>[]` instead of `[]`).
*   **If the error is an Invalid Override (e.g., "The parameter type doesn't match the overridden method"):**
    *   Widen the parameter type to match the superclass, OR
    *   Add the `covariant` keyword to the parameter if tightening the type is intentionally required by the domain logic.

**4. Verify fixes (Feedback Loop)**
Run the validator. Review errors. Fix.
```bash
dart analyze .
dart test
  • If
    dart analyze
    reports errors:
    Return to Step 3.
  • If
    dart test
    fails with a
    TypeError
    :
    You have introduced an invalid explicit cast (
    as T
    ) or accessed an uninitialized
    late
    variable. Locate the runtime failure and correct the type hierarchy or initialization order.
dart fix --apply

**3. 手动解决剩余错误**
查看剩余的分析器输出,并根据错误类型应用相应逻辑:

*   **如果错误是空安全问题(如“无法在可空接收者上访问属性”):**
    *   验证变量在逻辑上是否可为空。
    *   如果是,使用可选链式调用(`?.`)或提供回退值(`??`)。
    *   如果不是,且保证在其他地方已初始化,则在声明时标记`late`。
*   **如果错误是类型不匹配(如“参数类型'List<dynamic>'无法赋值给...”):**
    *   跟踪变量的初始化过程。
    *   在实例化时添加显式泛型类型注解(如`<int>[]`而非`[]`)。
*   **如果错误是无效重写(如“参数类型与被重写方法不匹配”):**
    *   扩大参数类型以匹配父类,或者
    *   如果领域逻辑确实需要缩小类型,则为参数添加`covariant`关键字。

**4. 验证修复(反馈循环)**
运行验证工具,查看错误,修复问题。
```bash
dart analyze .
dart test
  • 如果
    dart analyze
    报告错误:
    返回至步骤3。
  • 如果
    dart test
    TypeError
    失败:
    你引入了无效的显式转型(
    as T
    )或访问了未初始化的
    late
    变量。定位运行时故障并修正类型层次结构或初始化顺序。

Examples

示例

Example: Fixing Dynamic List Assignments

示例:修复动态列表赋值

Input (Fails Static Analysis):
dart
void printInts(List<int> a) => print(a);

void main() {
  final list = []; // Inferred as List<dynamic>
  list.add(1);
  list.add(2);
  printInts(list); // Error: List<dynamic> can't be assigned to List<int>
}
Output (Passes Static Analysis):
dart
void printInts(List<int> a) => print(a);

void main() {
  final list = <int>[]; // Explicitly typed
  list.add(1);
  list.add(2);
  printInts(list);
}
输入(静态分析失败):
dart
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>
}
输出(静态分析通过):
dart
void printInts(List<int> a) => print(a);

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

Example: Fixing Method Overrides (Contravariance)

示例:修复方法重写(逆变)

Input (Fails Static Analysis):
dart
class Animal {
  void chase(Animal a) {}
}

class Cat extends Animal {
  
  void chase(Mouse a) {} // Error: Tightening parameter type
}
Output (Passes Static Analysis):
dart
class Animal {
  void chase(Animal a) {}
}

class Cat extends Animal {
  
  void chase(covariant Mouse a) {} // Explicitly marked covariant
}
输入(静态分析失败):
dart
class Animal {
  void chase(Animal a) {}
}

class Cat extends Animal {
  
  void chase(Mouse a) {} // 错误:缩小参数类型
}
输出(静态分析通过):
dart
class Animal {
  void chase(Animal a) {}
}

class Cat extends Animal {
  
  void chase(covariant Mouse a) {} // 显式标记为covariant
}

Example: Fixing Null Safety with
late

示例:使用
late
修复空安全问题

Input (Fails Static Analysis):
dart
class Thermometer {
  String temperature; // Error: Non-nullable instance field must be initialized

  void read() {
    temperature = '20C';
  }
}
Output (Passes Static Analysis):
dart
class Thermometer {
  late String temperature; // Defers initialization check to runtime

  void read() {
    temperature = '20C';
  }
}
输入(静态分析失败):
dart
class Thermometer {
  String temperature; // 错误:非空实例字段必须初始化

  void read() {
    temperature = '20C';
  }
}
输出(静态分析通过):
dart
class Thermometer {
  late String temperature; // 将初始化检查延迟到运行时

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