每当我捕获异常并处理它时,它似乎仍然在$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
变量收集捕获的异常?
答案 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
}