gpt4 book ai didi

powershell - 有没有办法通过自定义 System.Management.Automation.ErrorRecord 抛出?

转载 作者:行者123 更新时间:2023-12-03 00:06:07 26 4
gpt4 key购买 nike

我想抛出带有一些附加属性的自定义 System.Management.Automation.ErrorRecord:ContextMessageSqlCmdHeader

我尝试创建继承自 System.Management.Automation.ErrorRecord 的新类:

class SqlRequestException : System.Management.Automation.ErrorRecord
{
[hashtable]$SqlCmdHeader

[string]$ContextMessage

SqlRequestException() { }

SqlRequestException(
[string]$message,
[hashtable]$sqlCmdHeader,
[System.Management.Automation.ErrorRecord]$errorRecord
) : base($errorRecord, $null)
{
$this.SqlCmdHeader = $sqlCmdHeader
$this.ContextMessage = $message
}
}

但是当我通过这段代码抛出错误时:

try
{
#exceptions is risen here
}
catch
{
throw ([SqlRequestException]::New(
"Some context message of exception which will help to understand the error without additional debugging of code",
$sqlHeader,
$_))
}

我只是进入了调用者 System.Management.Automation.ErrorRecord 而没有我很棒的属性。看起来 throw 将我的对象转换为 System.Management.Automation.ErrorRecord 并丢失了属性。

我想请你们帮我在我的脚本中实现这个逻辑。任何帮助将不胜感激!

更新

我无法更改来电者的密码。它总是解析错误并将其写入日志:

try
{
# calling the method from module where I try to throw custom ErrorRecord
}
catch
{
Write-Log -Text $_
}

我不能使用 System.Exception 因为当我抛出创建的异常时,所有原始信息(例如 InvocationInfoScriptStackTrace 等)都来自ErrorRecord 丢失。我找不到 throw 语句的源代码来理解它到底是如何工作的(也许有人可以指点我?)

我看到有 TargetObject 属性可用于存储一些附加信息,但我看不到在 throw 语句之前将某些内容放入该属性的方法,因为该属性为 ReadOnly,我认为该属性并非旨在存储其他用户的数据。

最佳答案

虽然 System.Management.Automation.ErrorRecord类在技术上不是密封的,文档也没有提到子类化,看起来子类化 ErrorRecord 实际上不支持:

如您所见,您抛出 的原始SqlRequestException 实例并没有像这样进入调用堆栈,大概 因为涉及复制到基类的实例。

改为子类 System.Exception 并让 PowerShell 自动将您的异常包装在 [ErrorRecord] 实例中,该实例的 .Exception 稍后可以查询的属性:

# Make your custom exception derive from System.Exception.
class SqlRequestException : System.Exception
{
[hashtable]$SqlCmdHeader
[string]$ContextMessage

# Construct the exception with the one passed as an
# argument as the *inner* exception.
SqlRequestException(
[string]$contextMessage,
[hashtable]$sqlCmdHeader,
[exception]$innerException
) : base($innerException.Message, $innerException)
{
$this.ContextMessage = $contextMessage
$this.SqlCmdHeader = $sqlCmdHeader
}
}

try { # Outer `try` to simulate a caller.
try # Your code.
{
[int]::Parse('not a number') # Sample exception.
}
catch
{
# Throw your custom exception that wraps the original exception
# ($_.Exception) via its .InnerException property.
# PowerShell itself then automatically wraps your custom exception in
# an [ErrorRecord] instance.
throw ([SqlRequestException]::New(
'custom message',
@{ header1 = 'foo' },
$_.Exception))
}
} catch { # The (simulated) caller's catch block.
# Now you can access your custom properties via $_.Exception.
@"
Error: $_
Custom properties:
ContextMessage: $($_.Exception.ContextMessage)
SqlCmdHeader: $($_.Exception.SqlCmdHeader | Out-String)
"@
}

上面的结果如下,表明两个自定义属性都被传递了:

Error: Exception calling "Parse" with "1" argument(s): "Input string was not in a correct format."
Custom properties:
ContextMessage: custom message
SqlCmdHeader:
Name Value
---- -----
header1 foo

自定义异常的消息是原始异常的消息;要获取原始异常的详细信息,请访问 $_.InnerException

关于powershell - 有没有办法通过自定义 System.Management.Automation.ErrorRecord 抛出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60543128/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com