为什么`exit`会抑制Select-Xml的错误?

时间:2019-01-28 15:33:52

标签: powershell error-handling

我在Powershell w.r.t中遇到了(对我而言)非常令人惊讶的错误抑制行为。到Select-Xml Commandlet。为了显示(IMHO)的预期行为,我首先显示一个Get-Content的最小示例:

获取内容

try {
    Get-Content -Path "NonExistingFile.txt"
}
finally {
    exit 42
}

如预期的那样,这将引发错误(包括消息):

PS > .\gc-nonexistingfile.ps1
Get-Content : Der Pfad "NonExistingFile.txt" kann nicht gefunden werden, da er nicht
vorhanden ist.
In gc-nonexistingfile.ps1:2 Zeichen:5
+     Get-Content -Path "NonExistingFile.txt"
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (...xistingFile.txt:String) [Get-Content], 
                              ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

PS > echo $LASTEXITCODE
42

Select-Xml

如果我对Select-Xml做同样的事情,错误消息将被吞没,但是仅当我使用exit关键字时。如果我删除了exit行,则报告的错误如上所述:

try {
    Select-Xml -Path "NonExistingFile.xml" -XPath "*"
}
finally {
    exit 43  # comment this out to get error message
}

退出行为:

PS > .\sx-nonexistingfile.ps1
PS > echo $LASTEXITCODE
43

没有退出(为清楚起见直接调用命令行开关):

PS > Select-Xml -Path "NonExistingFile.xml" -XPath "*"
Select-Xml : Der Pfad "NonExistingFile.xml" kann nicht gefunden werden, da er nicht
vorhanden ist.
In Zeile:1 Zeichen:1
+ Select-Xml -Path "NonExistingFile.xml" -XPath "*"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (...xistingFile.xml:String) [Select-Xml],
                              ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SelectXmlCommand

问题

我的问题:为什么有区别?并且:尽管我使用Select-Xml结束脚本,我怎么能exit明显地抛出错误?

1 个答案:

答案 0 :(得分:0)

@Mathias R. Jessen's suggestion in the comment之后,我确定的最佳解决方案是脚本中的catch块:

  1. 引入自定义错误报告功能
  2. 显式捕获块中使用它以抛出任何异常

有了这个

function Report-Error ($Error)
{
    $FormatString = "{0} : {1}`n{2}`n" +
                    "    + CategoryInfo          : {3}`n" +
                    "    + FullyQualifiedErrorId : {4}`n"
    $ErrorFields = $Error.InvocationInfo.MyCommand.Name,
                   $Error.ErrorDetails.Message,
                   $Error.InvocationInfo.PositionMessage,
                   $Error.CategoryInfo.ToString(),
                   $Error.FullyQualifiedErrorId
    Write-Host -Foreground Red -Background Black ($FormatString -f $ErrorFields)
}

脚本变为:

try {
    Select-Xml -Path "NonExistingFile.xml" -XPath "*"
}
catch {
    Report-Error $_
}
finally {
    exit 43
}