如何从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
相关产品推荐
相关产品推荐

