powershell - 有没有办法通过自定义 System.Management.Automation.ErrorRecord 抛出?
问题描述
我想System.Management.Automation.ErrorRecord
用一些额外的属性来自定义:ContextMessage
和SqlCmdHeader
.
我试图创建继承自的新类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
,因为当我抛出创建的异常时,所有原始信息(例如InvocationInfo
,ScriptStackTrace
等等)ErrorRecord
都丢失了。我找不到throw
声明的源代码来理解它是如何工作的(也许有人可以指出我?)
我看到有一个TargetObject
属性可以用来存储一些额外的信息,但是我看不到在声明之前将一些东西放到属性中的方法,throw
因为该属性是ReadOnly
并且我认为该属性不是为了存储额外的用户数据而设计的。
解决方案
虽然System.Management.Automation.ErrorRecord
该类在技术上不是密封的并且文档没有提到子类化,但看起来ErrorRecord
实际上不支持子类化:
正如您所经历的那样,SqlRequestException
您没有将原始实例throw
放在调用堆栈中,大概是因为涉及复制到基类的实例中。
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
.
推荐阅读
- r - 在 ddply 函数中添加时间趋势变量
- deep-learning - 测试时框架caffe不起作用
- html - SVG 图像未与 100vh 视口中的“object-fit”等价物对齐
- javascript - 在 Kendo UI TreeList 中拖动节点时如何更改图标/拖动线索?
- xml - 为什么 Dynamics AX 集成框架不接受 xsi:type 属性上的命名空间前缀,我该如何做?
- python - 在具有 Python UCS4 的 Ubuntu 14.04 中创建 Virtualenv
- sql - 在 sqlite 中向该表添加增长列
- ruby-on-rails - 我的服务对象模块中的未定义方法
- apiconnect - IBM APIConnect 是否有 IP 白名单或黑名单?
- java - 失败:org.apache.maven plugins:maven-jar-plugin:2.6:test-jar