如何防止$ error收集捕获的异常?

时间:2014-10-22 11:59:17

标签: powershell try-catch

每当我捕获异常并处理它时,它似乎仍然在$error变量内。例如,使用以下代码作为示例repro:

$error.clear(); # To make the example as clear as possible

# Lots of logic happens here that leaves a trace in $error. I want to see these
# traces at the very end of my script. However, before the end, seomething along
# these lines happens:

try {
    Write-Output "Trying...";
    $myVar = $null; # Assume $null is actually the result of a complex function
    if ($myVar.ToString() -match "my pattern") {
        # More logic here
    }
} catch {
    Write-Output "Catching...";
} 

# Even more stuff happens here, which may (or may not) add interesting stuff to
# the $error variable.

# Here, at the end of my script, I'm only interested in errors *not* from the 
# try..catch bit, but alas, the Count will inlcude those too...
Write-Output ("Ending... with error.Count = {0}" -f $error.Count);

捕获到错误,但此脚本末尾的$error.Count仍为“1”。但是,在我的情况下,我正在处理catch中的错误,我不想被脚本末尾的错误所困扰。

我试图重写导致异常的命令的逻辑,希望ErrorAction参数可以解决问题,但这不起作用。

我也尝试了我的Google-fu(this query上的各种变体)和SO-fu(this query上的变体),但它们都是空的。

在我结束之前,让我详细说明我的场景的背景,以防我遇到XY问题。上面的代码段表示较长部署脚本中的一小段代码。在该代码块之前和之后,可能还有其他事情会在$error变量中留下痕迹。出于这个原因,我认为我无法在开始时清除错误(我想保留可能已存在的东西)。

结论:我如何阻止$error变量收集捕获的异常?

2 个答案:

答案 0 :(得分:0)

如果不是你想要的东西,我会删除它,但我试着这样做。它有一个警告你可能会自己看到我会解决。

$error.clear()
$addressedErrors = @()

Get-ChildItem c:\tempo1 -ErrorAction SilentlyContinue

try{
    Get-ChildItem c:\tempo2 -ErrorAction Stop
} Catch {
    $addressedErrors += [regex]::escape($error[0].Exception.Message)
}
Get-ChildItem c:\tempo3 -ErrorAction SilentlyContinue


$regex = "($($addressedErrors -join '|'))"
$uncaughtErrors = $error | Where-Object{$_.Exception.Message -notmatch $regex}

$uncaughtErrors.Count

所以我清除$error从一个干净的石板开始。在我的测试中,我执行了3 Get-ChildItem,它们应该失败。我只抓住那个。

Catch中,我收到错误消息以及这些消息的构建和数组。还可以使用静态escape正则表达式方法来转义正则表达式特殊字符。我考虑过在这种情况下使用了一个例子[System.Management.Automation.ItemNotFoundException],但这并不足以让我相信这种方法。

在我/您的脚本结束时,我收集错误消息并构建一个正则表达式字符串。获取$error对象并输出尚未解决的错误。

<强>买者

我知道有一件事是错误的,如果完全相同的erorr发生两次但是解决了一次。 -notmatch会过滤掉两次出现。可以通过使用erorr索引构建复杂的哈希表来解决这个问题,但我不知道你是否已经提交了这个解决方法。

答案 1 :(得分:0)

我在catch块中使用$Error.RemoveAt(0)的方法来帮助解决此问题。 我发现自己在计划任务中使用了此功能,在该任务中,我检查$ Error的计数并在遇到任何未处理的异常时抛出退出代码。

$Error.RemoveAt(0)中的零是索引号,从本质上消除了最新的错误。希望可以消除将您带到catch块的错误。

try {
    $FormattedDate = Get-Date -Date $Date -Format "yyyy-MM-dd" -ErrorAction Stop
}
catch {
    $Error.RemoveAt(0)
    $FormattedDate = $null
}