You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Dart模式匹配中获取实际错误信息?

解决Dart模式匹配转JSON时的错误定位问题

针对你在Game.fromJson中使用模式匹配转换JSON,却无法获取具体错误信息的问题,这里提供两种实用方案:

方案一:手动字段验证+收集错误信息

直接逐个检查JSON字段的类型和存在性,收集所有不符合要求的问题后再抛出异常,能清晰定位错误:

factory Game.fromJson(Map<String, dynamic> json) {
  final errorMessages = <String>[];

  // 验证每个字段的类型
  if (json['id'] is! String) errorMessages.add('字段id必须是String类型');
  if (json['bggId'] is! String) errorMessages.add('字段bggId必须是String类型');
  if (json['name'] is! String) errorMessages.add('字段name必须是String类型');
  if (json['imageUrl'] != null && json['imageUrl'] is! String) errorMessages.add('字段imageUrl如果提供必须是String类型');
  if (json['description'] is! String) errorMessages.add('字段description必须是String类型');
  if (json['yearPublished'] is! int) errorMessages.add('字段yearPublished必须是int类型');
  if (json['minPlayers'] is! int) errorMessages.add('字段minPlayers必须是int类型');
  if (json['maxPlayers'] is! int) errorMessages.add('字段maxPlayers必须是int类型');

  // 有错误则抛出包含具体信息的异常
  if (errorMessages.isNotEmpty) {
    throw FormatException('加载Game失败:${errorMessages.join(';')}');
  }

  // 验证通过后直接转换
  return Game(
    id: json['id'] as String,
    bggId: json['bggId'] as String,
    name: json['name'] as String,
    imageUrl: json['imageUrl'] as String?,
    description: json['description'] as String,
    yearPublished: json['yearPublished'] as int,
    minPlayers: json['minPlayers'] as int,
    maxPlayers: json['maxPlayers'] as int,
  );
}

方案二:封装验证扩展方法

通过扩展方法封装字段验证逻辑,让代码更简洁,同时保留错误信息的清晰度:

// 给Map<String, dynamic>添加验证扩展
extension JsonFieldValidator on Map<String, dynamic> {
  // 获取可选字段,类型不匹配时返回null
  T? getOptional<T>(String key) {
    final value = this[key];
    return value is T ? value : null;
  }

  // 获取必填字段,类型不匹配时抛出具体错误
  T getRequired<T>(String key) {
    final value = this[key];
    if (value is T) return value;
    throw FormatException('字段$key的类型错误,预期${T.runtimeType},实际${value.runtimeType}');
  }
}

// 改造后的fromJson构造函数
factory Game.fromJson(Map<String, dynamic> json) {
  try {
    return Game(
      id: json.getRequired<String>('id'),
      bggId: json.getRequired<String>('bggId'),
      name: json.getRequired<String>('name'),
      imageUrl: json.getOptional<String>('imageUrl'),
      description: json.getRequired<String>('description'),
      yearPublished: json.getRequired<int>('yearPublished'),
      minPlayers: json.getRequired<int>('minPlayers'),
      maxPlayers: json.getRequired<int>('maxPlayers'),
    );
  } catch (e) {
    throw FormatException('加载Game失败:${e.toString()}');
  }
}

为什么原代码无法获取具体错误

原代码中的_ =>是模式匹配的默认分支,所有不满足第一个完整模式的情况都会进入这里,但Dart的模式匹配不会自动记录具体哪个字段不匹配,因此需要手动添加验证逻辑来捕获细节错误。

内容的提问来源于stack exchange,提问作者Gregg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 12:46:22