如何重新抛出异常并保留堆栈跟踪?

41

这段代码:

try {
  try {
    throw 1;
  } catch (e, s) {
    print("$e $s");
    throw e;
  }
} catch (e2, s2) {
  print("$e2 $s2");    
}

打印:

1 #0      main (file:///.../test.dart:34:7)

1 #0      main (file:///.../test.dart:37:7)

所以原始的堆栈跟踪完全丢失了。有没有办法重新抛出并保留堆栈跟踪?


如果你只是rethrow会发生什么? - Ladicek
@Ladicek,Dart中是否有rethrow关键字?我在网上找不到它的证据,而且我的Dart安装程序也无法理解它。 - Darshan Rivka Whittle
@DarshanComputing 请参考规范的第12.8.1章节。 - Ladicek
@Ladicek 啊,我找到了,谢谢。有趣的是它不是一个关键字,而且目前是使用 throw 实现的。 - Darshan Rivka Whittle
@DarshanComputing 以前只有 throw,但是一段时间以来已经改为 rethrow - Ladicek
@Ladicek 你是指在规范中吗?啊,这很有道理。也许在M4版本中,虚拟机、dart2js等将会转换。太棒了,谢谢。 - Darshan Rivka Whittle
1个回答

54

在当前版本的Dart VM和 dart2js 中,使用 rethrow 可以支持重新抛出异常并保留堆栈跟踪:

void main() {
  try {
    try {
      throw 1;
    } catch (e, s) {
      print("$e $s");
      rethrow;
    }
  } catch (e2, s2) {
    print("$e2 $s2");    
  }
}

这将产生:

1 #0      main (file:///home/darshan/so/stacktrace.dart:4:7)
1 #0 main (file:///home/darshan/so/stacktrace.dart:4:7) #1 main (file:///home/darshan/so/stacktrace.dart:7:7)

1
所以,区别在于你只是throw,而@JustinFagnani正在执行throw e - Alex F
3
是的,throw e; 是一个正常的抛出异常语句,而 throw; 是当前重抛异常的写法。 - Darshan Rivka Whittle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接