假设我有以下构造:
Try
Dim f As FileInfo = Nothing
f.Delete()
... some other stuff...
Catch ex as Exception
Throw
End Try
在这个简单的示例中,f.Delete
将抛出NullReferenceException。
为什么此异常的StackTrace中的问题行指向Throw
语句而不指向行f.Delete()
?
如何保留Try / Catch,但将CORRECT堆栈跟踪指向f.Delete()
作为问题的根源?
答案 0 :(得分:2)
1。为什么此异常的StackTrace中的问题行指向Throw语句而不指向f.Delete()行?
这取决于您正在查看的堆栈跟踪:由重新抛出(catch块内的Throw
)生成的堆栈跟踪,还是第一个异常被捕获?
在Catch ex As Exception
行设置断点并使用调试器检查ex
;您将看到指向f.Delete()
的堆栈跟踪。
Throw
表示“重新抛出”,即原始堆栈跟踪将被保留... 但是,对于相同的方法调用,您不会在堆栈跟踪中获得两个条目:如果异常在最初导致异常的同一方法中被重新抛出,堆栈跟踪将只包含指向最终重新抛出的条目。
2。如何保留Try / Catch,但将CORRECT堆栈跟踪指向f.Delete()作为问题的根源?
请记住,重新投掷基本上意味着,“我错了,毕竟我不知道如何处理这个例外。”因此,您可以使用异常过滤器(Catch … When <boolean-expression>
)来判断您是否 可以处理之前的异常过滤器而不是重新投掷。如果您在捕获之前可以确定,则不需要重新抛出,并且不会修改堆栈跟踪。
将f.Delete()
放在另一个方法中。这样,它在堆栈跟踪中获得自己的堆栈帧/行,并且不会被重新Throw
覆盖。
(或者,只是为了重新抛出它而不会捕获异常。)
答案 1 :(得分:0)
我想这也可以提供正确的例外(至少在&#34;内部&#34;例外):
Try
Dim f As FileInfo = Nothing
f.Delete()
... some other stuff...
Catch ex as Exception
Throw New Exception("Failed in Method X", ex)
End Try