【问题标题】:Cannot catch or trap syntax error无法捕获或捕获语法错误
【发布时间】:2016-11-09 12:46:47
【问题描述】:

我知道 powershell 在处理语法错误和退出代码时的不良行为。我有以下重现案例,应该被陷阱或 try catch 块捕获,但它们都不会被触发,即使 $ErrorActionPreference 设置为 stop

这里的代码一直以错误代码0退出,这很烦人,因为没有调用陷阱机制来处理错误:

$ErrorActionPreference = "stop"
trap [Exception] {
    echo "Trap encountered"
    exit(1)
}

Try
{

   function foo($path, $path)
   {
   }

}

Catch
{
    echo "Caught something"
    exit(1)
}

有人知道在这种情况下我可以如何欺骗 powershell 正确退出吗?脚本中的语法错误会默默地破坏我们的 CI,这是一个很大的问题。

为了清楚起见:这已经在 Win 7 PS 3.0 上测试和复制

编辑2:为了避免更多人说我不会通过这个来捕捉语法错误。 Powershell 的设计与您所知道的大多数其他脚本或编程语言不同。

您可以捕获语法错误,因为它们被视为终止错误。

如果出现语法错误或内存不足,则为终止错误。可以捕获和处理终止错误。

http://www.vexasoft.com/blogs/powershell/7255220-powershell-tutorial-try-catch-finally-and-error-handling-in-powershell

【问题讨论】:

  • 对我来说出错了:“function foo($path, $path) + ~~~~~~ Duplicate parameter $path in parameter list。”
  • 在我的系统上,powershell -command "function foo($a, $a) {}" 的退出代码为 1,而成功运行的退出代码为 0。从 CI 中检测错误至少应该是可行的。如果你真的想从 PowerShell 本身处理这个问题,你当然可以递归调用 (blech) 或者你可以尝试利用 Parser 类(从 3.0 开始)在执行之前解析任何脚本。
  • @4c74356b41 会,但不会调用陷阱,如果您检查退出代码,它将为 0,无论红色错误文本如何。
  • @JeroenMostert 这是一个示例,我们的脚本要复杂得多,我们的 CI 执行 powershell -f tempfile.ps1。似乎不鼓励使用 powershell -command。解析器在这里不起作用,因为这个脚本被 CI 放入一个临时文件中,我无权访问它。
  • @Samuel:它的目的是作为一个例子。 powershell -f .\script.ps1 在退出代码方面做同样的事情。从cmd (powershell somethingsomething || echo %errorlevel%) 亲自尝试。我也不明白为什么解析器不起作用。脚本由 CI 放在那里,但肯定确定脚本的内容吗?否则你的问题更多是关于如何让你的 CI 不输出无效的脚本......

标签: powershell windows-7 powershell-3.0


【解决方案1】:

Try/Catch 捕获执行错误,而不是解析器错误。解析器错误将在 powershell 甚至开始执行脚本之前发生。与其直接调用脚本,不如通过帮助脚本调用它,众所周知,它总是具有良好的语法。例如ScriptInvoker.ps1

param (
    [Parameter(Mandatory=$true,Position=1)]
    [string]$Path
)
$ErrorActionPreference = "stop"

try { &$Path }
catch { exit(1) }

现在您的 CI 系统只需将您的临时脚本输出到temp.ps1,而不是调用powershell -File temp.ps1,而是使用powershell -File ScriptInvoker.ps1 temp.ps1

【讨论】:

  • 您对 powershell 的假设似乎是错误的: > 如果您犯了语法错误或内存不足,那就是终止错误。可以捕获和处理终止错误。 vexasoft.com/blogs/powershell/…
  • 为什么说语法错误是终止错误。 powershell 执行时出现终止错误。甚至在任何代码开始执行之前都会发生语法错误。
  • 我不这么说,这是我评论中提到的链接的引用。此外,它适用于 Win 10
【解决方案2】:

我认为 PS 脚本分析器可以满足您的需求。 https://github.com/PowerShell/PSScriptAnalyzer

所以对我来说它是这样工作的:

尝试 {Invoke-ScriptAnalyzer -ErrorAction Stop -Path .\ } 捕捉 {Write-Output $_} Invoke-ScriptAnalyzer:文件 C:\Users\gleb_boushev\Desktop\Untitled2.ps1 中的解析错误:第 10 行第 24 列的参数列表中的参数 $path 重复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 2013-09-09
    • 2020-04-06
    相关资源
    最近更新 更多