【问题标题】:Catching script-terminating errors only in PowerShell仅在 PowerShell 中捕获脚本终止错误
【发布时间】:2021-08-30 20:14:49
【问题描述】:

PowerShell 5.1

我编写了一个包装脚本,它启动另一个脚本,记录其输出(通过 Start-Transcript),如果它以非零代码退出,则发送一封电子邮件,最后根据文件大小轮换日志文件。

我只想捕获会导致被调用脚本在自行执行时退出的错误。 (脚本终止术语基于此处的讨论:https://github.com/MicrosoftDocs/PowerShell-Docs/issues/1583)。

try { 
    Invoke-Expression "& '$Script' $ArgList"
    $err = $LastExitCode
} catch { 
    Write-Error -ErrorRecord $_
    $err = 1
}

抓住这个:

$ErrorActionPreference = 'Stop'
Remove-Item -Path DoesntExist

或者这个:

throw "Error"

但不是这个(脚本应该继续执行,如果不是通过日志脚本调用的话):

Test-Path -Foo bar

有可能吗?还是有更好的方法?

【问题讨论】:

  • 不要定义$ErrorActionPreference变量,而是在cmdlet中设置它,例如忽略Test-Path -Foo bar -ErrorAction SilentlyContinue的错误并将其用于Remove-Item -Path DoesntExist -ErrorAction Stop
  • 我希望被调用的脚本表现得像单独执行时一样。在此示例中,Test-Path 失败,但脚本继续运行。但是当我通过包装脚本调用它时,它会捕获该异常并停止。
  • 感谢您的提示,我会研究替代方案。

标签: powershell exception


【解决方案1】:

try { ... } catch { ... } statement 不区分 语句 终止 (Test-Path -Foo bar) 和 脚本 终止错误 (throw "Error")both 子类型的 terminating 错误触发 catch 块。

换句话说:任何本质上的语句终止错误,例如1 / 0Test-Path -Foo bar(一个调用语法错误,因为没有这样的参数)总是 触发你的 catch 块。

任何非终止错误也将提升为一个脚本终止一个,无论是$ErrorActionPreference = 'Stop'-ErrorAction Stop (这就是你想要的)。

  • 顺便说一句:$ErrorActionPreference = 'Stop' - 与 -ErrorAction Stop 不同 - 还会将 statement 终止错误提升为 script 终止错误,这只是问题之一PowerShell 令人惊讶的复杂错误处理的各个方面,在您的问题中链接到的GitHub docs issue 中进行了详细讨论。

相关信息(不能解决您的问题):

关于事后分析错误分析,你能做的最好的分析发生了什么样的错误是检查它是否是一个脚本终止错误由 throw 语句触发,通过检查 $_.Exception.WasThrownFromThrowStatement,但您通常无法区分语句终止错误、非终止错误和提升的非终止错误到一个脚本终止的脚本。

GitHub issue #4781 讨论了检测错误的内在有效“致命性”的潜在未来改进。

【讨论】:

    猜你喜欢
    • 2021-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多