PowerShell异常处理疑问:FileNotFoundException为何被RuntimeException捕获
原因说明
你观察到的现象是PowerShell throw 关键字的默认设计导致的,和原始异常的继承链无关:
- PowerShell中直接使用
throw+ 非RuntimeException派生的异常实例时,不会直接抛出你创建的FileNotFoundException,而是自动生成一个System.Management.Automation.RuntimeException实例作为外层异常,将你定义的异常存到该实例的InnerException属性中,最终实际触发catch逻辑的是外层的RuntimeException,因此会匹配到你写的catch块。 - 你可以通过在catch块中输出异常信息验证这一逻辑:
try { throw [System.IO.FileNotFoundException]::new("Thrown a file not found exception") } catch [System.Management.Automation.RuntimeException] { Write-Output "Entered catch" Write-Output "实际捕获的异常类型:$($_.Exception.GetType().FullName)" Write-Output "内部原始异常类型:$($_.Exception.InnerException.GetType().FullName)" }
实现预期行为的方法
如果需要直接抛出原始类型的异常、让对应类型的catch块正常匹配,需要使用$PSCmdlet.ThrowTerminatingError()方法抛出封装好的错误记录,示例如下:
[CmdletBinding()] param() try { $originalException = [System.IO.FileNotFoundException]::new("Thrown a file not found exception") $errorRecord = [System.Management.Automation.ErrorRecord]::new( $originalException, "CustomFileNotFound", [System.Management.Automation.ErrorCategory]::ObjectNotFound, $null ) $PSCmdlet.ThrowTerminatingError($errorRecord) } catch [System.Management.Automation.RuntimeException] { Write-Output "Entered RuntimeException catch" } catch [System.IO.FileNotFoundException] { Write-Output "Entered FileNotFoundException catch" }
运行上述代码会进入FileNotFoundException对应的catch块,符合你最初的预期。
注:$PSCmdlet变量仅在声明了[CmdletBinding()]的高级函数/脚本中可用,是PowerShell推荐的抛出终止性错误的标准方案。
内容的提问来源于stack exchange,提问作者Fulcro
相关产品推荐
相关产品推荐

