什么是Dart中的_TypeError?如何捕获及在单元测试中校验该异常?
问题解答
1. _TypeError的定义
Dart中以下划线开头的类型都是库私有类型,_TypeError是dart:core库的内部私有实现类,没有对外暴露官方文档,也不允许外部代码直接引用。它继承自Error类,专门用于触发运行时类型不匹配错误:当运行时发生子类型校验失败(比如把int类型的dynamic值赋值给String类型变量)时,就会抛出该类的实例。
官方不对外暴露该类型的核心原因是它属于SDK内部实现细节,不同运行环境(Dart VM、dart2js、Dart WASM)的实现可能存在差异,不希望开发者直接依赖该类型做业务逻辑。
2. 精准捕获的实现
因为_TypeError是私有类型,所以无法直接用on _TypeError catch(e)的语法捕获。但它实现了公开的TypeError接口,你可以直接捕获公开的TypeError类型:
void main() { dynamic x = 1; try { String y = x; } on TypeError catch (e) { print('捕获到类型错误: $e'); } }
如果需要更精准的校验(比如区分开其他TypeError子类),可以在catch块内判断运行时类型:
catch (e) { if (e.runtimeType.toString() == '_TypeError') { // 处理对应的类型错误 } else { rethrow; // 其他异常继续抛出 } }
3. 单元测试中预期抛出类型错误
你原有的测试代码存在两个问题:一是变量声明冲突、变量未定义的语法错误,二是throwsException只会匹配抛出Exception类型的情况,而_TypeError属于Error类型,不属于Exception,所以匹配失败。
正确的写法是配合throwsA和isA匹配器校验TypeError类型:
test('throws a TypeError when type mismatch', () { dynamic x = 1; expect(() { String y = x; }, throwsA(isA<TypeError>())); });
如果需要更精准匹配错误内容,可以加上错误信息校验:
test('throws correct subtype error message', () { dynamic x = 1; expect( () => String y = x, throwsA( isA<TypeError>().having( (e) => e.toString(), 'error message', contains("type 'int' is not a subtype of type 'String'"), ), ), ); });
内容的提问来源于stack exchange,提问作者Vega180
相关产品推荐
相关产品推荐

