在 Visual Basic 中,异常处理使用 Try...Catch...Finally 块。要在捕获后重新抛出异常,即将其传递给调用栈中的其他地方,可以使用 Throw 或 Throw ex 运算符。
区别:
Throw(无参数)重新抛出当前异常,并保留原始的调用栈(Call Stack)。Throw ex 抛出异常对象,但重置调用栈—关于实际问题发生位置的信息丢失。推荐使用不带参数的 Throw 进行正确的异常重抛,特别是在异常未被修改的情况下。
正确的重抛示例:
Try DangerousOperation() Catch ex As Exception ' 日志记录... Throw ' 保留调用栈 End Try
不正确的方式:
Try DangerousOperation() Catch ex As Exception Throw ex ' 调用栈重置,诊断困难 End Try
如果您使用 Throw ex 而不是 Throw,调用栈会发生什么?
使用不带参数的
Throw将保留原始调用栈—异常发生的地方。如果使用Throw ex,调用栈将从当前行开始,原始发生地点信息丢失。这会增加调试的难度,因为您看不到代码的哪个部分出现了问题。
故事
在一个大型银行项目中,开发人员使用
Throw ex来抛出逻辑错误。在分析日志时,发现无法确定异常发生的地点,因为缺少正确的跟踪。
故事
在数据访问层内部使用
Throw来重新抛出 SqlException,但在某些情况下,代码自动格式化工具会把它自动替换为Throw ex。这打破了自动从日志中提取数据的系统,并增加了对事件响应的时间。
故事
尝试修改 Exception 对象并通过不带参数的
Throw抛出,导致更改未在日志中反映——只有显式创建一个新异常对象并保存原始异常作为 InnerException 才能解决问题。