我无法抓住以下示例中DriveNotFoundException
生成的Get-PSDrive
:
try {
# Assumes no Q:\ drive connected.
$foo = Get-PSDrive -name 'Q' -ErrorAction Stop
}
catch [System.Management.Automation.DriveNotFoundException] {
Write-Output "Drive not found."
}
catch {
Write-Output "Something else went wrong."
}
这应该打印以下内容:
PS C:\temp> .\foo.ps1
Drive not found.
PS C:\temp>
相反,我得到:
PS C:\temp> .\foo.ps1
Something else went wrong.
PS C:\temp>
我正在使用Powershell 2.0,如果这是相关的。
答案 0 :(得分:5)
问题是因为-ErrorAction Stop
正在更改try / catch块所看到的Exception类型。
您可以通过捕获ActionPreferenceStopException
类型来证明这一点。因此,让我们运行一些故障排除代码,看看发生了什么:
try {
# Assumes no Q:\ drive connected.
$foo = Get-PSDrive -name 'Q' -ErrorAction Stop
}
catch [System.Management.Automation.DriveNotFoundException] {
Write-Output "Drive not found."
}
catch [System.Management.Automation.ActionPreferenceStopException] {
Write-Output "Stop Exception."
write-host "Caught an exception:" -ForegroundColor Red
write-host "Exception Type: $($_.Exception.GetType().FullName)" -ForegroundColor Red
write-host "Exception Message: $($_.Exception.Message)" -ForegroundColor Red
}
catch
{
write-host "Caught an exception:" -ForegroundColor Red
write-host "Exception Type: $($_.Exception.GetType().FullName)" -ForegroundColor Red
write-host "Exception Message: $($_.Exception.Message)" -ForegroundColor Red
}
返回以下输出:
Stop Exception.
Caught an exception:
Exception Type: System.Management.Automation.DriveNotFoundException
Exception Message: Cannot find drive. A drive with the name 'Q' does not exist.
所以你看到try / catch抓住了[System.Management.Automation.ActionPreferenceStopException]
异常,即使异常类型 [System.Management.Automation.DriveNotFoundException]
里面< / em> catch块。
因此,我们可以使用@ haliphax解决方案的略微修改版本来处理它,这是检查ActionPreferenceStopException
catch块内的错误类型:
try {
# Assumes no Q:\ drive connected.
$foo = Get-PSDrive -name 'Q' -ErrorAction Stop
}
catch [System.Management.Automation.ActionPreferenceStopException] {
if ($Error[0].Exception.GetType().Name -eq 'DriveNotFoundException') {
Write-Output "Drive not found."
}
else {
Write-Output "Something else went wrong."
}
}
catch {
Write-Output "Something else went wrong."
}
答案 1 :(得分:3)
注意:以下内容部分是推测性的。如果我错了,请告诉我。
观察到的行为是PowerShell v1和v2 中可能是错误,其中 内部类型异常[System.Management.Automation.ActionPreferenceStopException]
catch
语句中try / catch
[System.Management.Automation.ActionPreferenceStopException]
阻止了掩饰原始异常的匹配逻辑。
我怀疑$Error[0].Exception
纯粹是一个永远不会暴露的内部异常的原因是catch
及其别名在$_.Exception
块内,{{ 1}},反映原始异常,即使在PowerShell v1和v2中 - $Errors
集合也不包含[System.Management.Automation.ActionPreferenceStopException]
的痕迹。
虽然错误已在v3 + 中修复,但v3 + 仍然,但现在 匹配[System.Management.Automation.ActionPreferenceStopException]
in typed { {1}}处理程序,大概是为了不破坏向后兼容性。
鉴于其通用性质,它在抓取catch
方面有很大的好处(它只是告诉您 cmdlet遇到了非终止错误)。
[System.Management.Automation.ActionPreferenceStopException]
或-ErrorAction Stop
而被视为终止。 因此,对于必须同时运行v2-的代码,我解决了以下问题:
$ErrorActionPreference = 'Stop'
答案 2 :(得分:2)
我意识到这是由于一些奇怪的行为(根据上面关于PowerShell的更高版本的评论),但这确实设法处理特定的错误:
try {
$foo = Get-PSDrive -name 'Q' -ErrorAction Stop
}
catch {
if ($Error[0].Exception.GetType().Name -eq 'DriveNotFoundException') {
Write-Output 'No such drive.'
}
else {
Write-Output 'Something else went wrong.'
}
}
答案 3 :(得分:1)
这只是我使用的代码最终版本的简短帖子,基于@ {HAL9256在his answer中提供的解释:
Get-PSDrive
这已经在PowerShell 2.0和Twitter上进行了测试。 4.0并适用于两者。我想在PowerShell 2.0环境中catch
语句中会出现一些其他异常,触发<PersonName Infant="false" NameNumber="2.1" NameReference="C04" PassengerType="CNN">
<GivenName>SALMAN</GivenName>
<Surname>KHAN</Surname>
</PersonName>
块,但在我的用例中,它是一个小风险可接受的风险,并将在稍后的脚本中触发不同的异常。