首页 > 解决方案 > PowerShell 记录所有未处理的异常

问题描述

我希望记录未处理的异常,因为我的脚本作为一种自动化工具运行,没有人在控制台上监控进度。我的想法是创建我自己的异常类,它有一个可以接受的构造函数,[InvokationInfo]这样我就可以用文件和行号信息记录错误,可能还有跟踪堆栈。目标是捕获尽可能多的异常类型并处理它们,但是catch对于实际上是我的代码失败的异常有一个通用的 final。我突然想到,整个脚本将是一个大的尝试/捕获,因此我没想到的任何事情(只要它正在终止)都会被捕获并记录下来。为此,我对此进行了模拟:

class UnhandledException : Exception {
    UnhandledException () : base () {
    }
    UnhandledException ([System.Management.Automation.InvocationInfo] $InvokationInfo) {
        Write-Host "Unhandled Exception in $([System.IO.Path]::GetFileName($InvokationInfo.ScriptName)) at line $($InvokationInfo.ScriptLineNumber)"
    }
}

CLS
try {
    1/0
} catch [System.IO.IOException] {
    # Handled exception types go here
} catch {
    $unhandledException = [UnhandledException]::new($PSItem.InvocationInfo)
    #throw $unhandledException 
}

这似乎运作良好,我正在争论是否需要最后一次抛出,或者我是否也可以从异常中终止脚本,因为根据定义,一旦我记录了该信息,并且可能抛出关于失败,无论如何我都会退出脚本。

我的问题是,当脚本作为静默命令行实用程序运行时,这是处理异常的适当方法吗?我真的不希望出现这样的情况,如果控制台正在显示,那么 powershell 异常是可见的。我想尽可能安静地使用日志文件处理所有事情。然后可以将这些日志发送给我,以便我进行故障排除。

也就是说,我还没有找到任何关于将整个脚本包装在 try/catch 中的信息。 表明“抓住一切”是一种代码味道,但它也更多地谈论其他用户使用的方法,而不是实用程序脚本。如果我可以有我的常规日志,用于记录脚本的实际进度和数据错误,无法访问网络资源等,听起来std::uncaught_exception()它可能也是一个选项。所有这些都是我捕获的异常和处理。如果我可以定义一个仅用于其他未捕获异常的日志文件,那可能会更好,但我也没有为 PowerShell 找到类似的东西。所以我的方法是我的备用计划。除非我遗漏了什么,这是一个可怕的想法?

而且,需要明确的是,我不认为这将是唯一的异常处理。这将是最后的处理程序,记录我没有预料到、计划和处理的任何内容。

编辑:因此,我发现的一个限制trap是它仍然只捕获终止错误,理想情况下,我还希望获得持续错误的日志。为此,我一直在探索我尝试过的重定向

function LocalFunction {
    1/0
}

&{
CLS
LocalFunction 
Remove-Item 'Z:\no.txt' -errorAction silentlyContinue

Test-Path 'C:\'
Write-Host 'Continued'

} 2>> c:\errors.txt

这将成功地在函数中记录除以 0 错误和Remove-Itemwhen-errorAction的错误Continue(默认值),但是当我专门将它设置为SilentlyContinue它时不会记录。这似乎让我到达了我想去的地方,在控制台中会看到任何错误,而不是转到文本文件。然后,我可以在处理结束时测试该文件的大小,如果为 0 则删除或在记录某些内容时提供 toast 消息。

真正的问题是,&{}一旦它是一个 10,000 行的脚本,而不是一个小例子,基本上围绕整个脚本的构造是一个可行的选择吗?一般来说,这是一个好主意吗?或者这在开发过程中是否有用,但我只需要穿上我的大男孩裤子并实际处理所有可能的错误?

编辑 2:好吧,在我的实用程序的一个分支上做了一些测试之后,这种重定向方法实际上看起来很有希望。显然对性能没有影响,我什至可以将错误日志的内容添加到我的常规日志中,以使用户更轻松。好奇是否有人有一些反指示?

此外,稍微挖掘一下Invoke-Expression可能会更好,因为&操作员创建了一个子范围,这可能会导致问题,而Invoke-Expression不会。但另一方面Invoke-Expression,正则表达式在“不要那样做”层次结构中就在那里。让你走的东西嗯?

标签: powershellexception

解决方案


推荐阅读