考虑:
Invoke-WebRequest $sumoApiURL -Headers @{"Content-Type"= "application/json"} -Credential $cred -WebSession $webRequestSession -Method post -Body $sumojson -ErrorAction Stop
这会引发以下异常:
如何完全捕获它或至少过滤掉已经存在同名的资源。"?
使用$_.Exception.GetType().FullName
收益
System.Net.WebException
和$_.Exception.Message
给出了
远程服务器返回错误:(400)错误请求。
答案 0 :(得分:70)
PowerShell中的错误和异常是结构化对象。您在控制台上看到的错误消息实际上是一个格式化的消息,其中包含来自错误/异常对象的多个元素的信息。你可以自己(重新)自己构建它:
$formatstring = "{0} : {1}`n{2}`n" +
" + CategoryInfo : {3}`n" +
" + FullyQualifiedErrorId : {4}`n"
$fields = $_.InvocationInfo.MyCommand.Name,
$_.ErrorDetails.Message,
$_.InvocationInfo.PositionMessage,
$_.CategoryInfo.ToString(),
$_.FullyQualifiedErrorId
$formatstring -f $fields
如果您只想在catch
块中显示错误消息,则只需回显当前对象变量(在该点保存错误):
try {
...
} catch {
$_
}
如果您需要彩色输出,请使用Write-Host
格式化字符串,如上所述:
try {
...
} catch {
...
Write-Host -Foreground Red -Background Black ($formatstring -f $fields)
}
话虽如此,通常您不希望在异常处理程序中按原样显示错误消息(否则-ErrorAction Stop
将毫无意义)。结构化错误/异常对象为您提供了可用于更好地控制错误的其他信息。例如,您有$_.Exception.HResult
的实际错误编号。 $_.ScriptStackTrace
和$_.Exception.StackTrace
,因此您可以在调试时显示堆栈跟踪。 $_.Exception.InnerException
使您可以访问嵌套异常,这些异常通常包含有关错误的其他信息(顶级PowerShell错误可能有些泛泛)。您可以使用以下内容展开这些嵌套异常:
$e = $_.Exception
$msg = $e.Message
while ($e.InnerException) {
$e = $e.InnerException
$msg += "`n" + $e.Message
}
$msg
在您的情况下,您要提取的信息似乎在$_.ErrorDetails.Message
中。如果你有一个对象或一个JSON字符串,我不太清楚,但你应该能够通过运行
$_.ErrorDetails
成员的类型和值的信息。
$_.ErrorDetails | Get-Member
$_.ErrorDetails | Format-List *
如果$_.ErrorDetails.Message
是一个对象,您应该能够获得如下消息字符串:
$_.ErrorDetails.Message.message
否则您需要首先将JSON字符串转换为对象:
$_.ErrorDetails.Message | ConvertFrom-Json | Select-Object -Expand message
根据您处理的错误类型,特定类型的异常可能还包含有关手头问题的更具体信息。例如,在您的情况下,您有一个WebException
,除了错误消息($_.Exception.Message
)之外,还包含来自服务器的实际响应:
PS C:\> $e.Exception | Get-Member TypeName: System.Net.WebException Name MemberType Definition ---- ---------- ---------- Equals Method bool Equals(System.Object obj), bool _Exception.E... GetBaseException Method System.Exception GetBaseException(), System.Excep... GetHashCode Method int GetHashCode(), int _Exception.GetHashCode() GetObjectData Method void GetObjectData(System.Runtime.Serialization.S... GetType Method type GetType(), type _Exception.GetType() ToString Method string ToString(), string _Exception.ToString() Data Property System.Collections.IDictionary Data {get;} HelpLink Property string HelpLink {get;set;} HResult Property int HResult {get;} InnerException Property System.Exception InnerException {get;} Message Property string Message {get;} Response Property System.Net.WebResponse Response {get;} Source Property string Source {get;set;} StackTrace Property string StackTrace {get;} Status Property System.Net.WebExceptionStatus Status {get;} TargetSite Property System.Reflection.MethodBase TargetSite {get;}
为您提供如下信息:
PS C:\> $e.Exception.Response IsMutuallyAuthenticated : False Cookies : {} Headers : {Keep-Alive, Connection, Content-Length, Content-T...} SupportsHeaders : True ContentLength : 198 ContentEncoding : ContentType : text/html; charset=iso-8859-1 CharacterSet : iso-8859-1 Server : Apache/2.4.10 LastModified : 17.07.2016 14:39:29 StatusCode : NotFound StatusDescription : Not Found ProtocolVersion : 1.1 ResponseUri : http://www.example.com/ Method : POST IsFromCache : False
由于并非所有异常都具有完全相同的属性集,因此您可能希望针对特定异常使用特定处理程序:
try {
...
} catch [System.ArgumentException] {
# handle argument exceptions
} catch [System.Net.WebException] {
# handle web exceptions
} catch {
# handle all other exceptions
}
如果您无论是否发生错误都需要执行操作(清除任务,如关闭套接字或数据库连接),您可以在异常处理后将它们放在finally
块中:< / p>
try {
...
} catch {
...
} finally {
# cleanup operations go here
}
答案 1 :(得分:10)
我找到了它!
只需打印$Error[0]
以获取最后一条错误消息。
答案 2 :(得分:5)
您可以添加:
-ErrorVariable errvar
然后查看$errvar
。
答案 3 :(得分:3)
以下对我来说很好
try {
asdf
} catch {
$string_err = $_ | Out-String
}
write-host $string_err
其结果如下所示,而不是使用ErrorRecord对象作为字符串
asdf : The term 'asdf' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Users\TASaif\Desktop\tmp\catch_exceptions.ps1:2 char:5
+ asdf
+ ~~~~
+ CategoryInfo : ObjectNotFound: (asdf:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
答案 4 :(得分:2)
我一直回到这些问题,试图找出我真正感兴趣的数据到底埋在什么真正的整体ErrorRecord结构中。几乎所有答案都给出了有关如何提取特定数据位的零碎指令。
但是我发现使用ConvertTo-Json
转储整个对象非常有帮助,这样我就可以以一种易于理解的布局直观地看到一切。
try {
Invoke-WebRequest...
}
catch {
Write-Host ($_ | ConvertTo-Json)
}
使用ConvertTo-Json
的{{1}}参数扩展更深的值,但要格外小心,不要超过默认的-Depth
深度:P
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertto-json
答案 5 :(得分:0)
try {1/0} catch { $_ | Format-List * -Force | Out-String }
结果:
PSMessageDetails :
Exception : System.Management.Automation.RuntimeException: Attempted to divide by zero. ---> System.DivideByZeroException: Attempted to divide by zero.
--- End of inner exception stack trace ---
at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject :
CategoryInfo : NotSpecified: (:) [], RuntimeException
FullyQualifiedErrorId : RuntimeException
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}
try {1/0} catch { $_ | Format-List * -Force | Out-String ; $_.InvocationInfo | Format-List * -Force | Out-String }
结果:
PSMessageDetails :
Exception : System.Management.Automation.RuntimeException: Attempted to divide by zero. ---> System.DivideByZeroException: Attempted to divide by zero.
--- End of inner exception stack trace ---
at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject :
CategoryInfo : NotSpecified: (:) [], RuntimeException
FullyQualifiedErrorId : RuntimeException
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}
MyCommand :
BoundParameters : {}
UnboundArguments : {}
ScriptLineNumber : 1
OffsetInLine : 6
HistoryId : -1
ScriptName :
Line : try {1/0} catch { $_ | Format-List * -Force | Out-String ; $_.InvocationInfo | Format-List * -Force | Out-String }
PositionMessage : At line:1 char:6
+ try {1/0} catch { $_ | Format-List * -Force | Out-String ; $_.Invocat ...
+ ~~~
PSScriptRoot :
PSCommandPath :
InvocationName :
PipelineLength : 0
PipelinePosition : 0
ExpectingInput : False
CommandOrigin : Internal
DisplayScriptPosition :
try {1/0} catch { $Exception = $_; $Exception | Format-List * -Force | Out-String ; $Exception.InvocationInfo | Format-List * -Force | Out-String ; for ($i = 0; $Exception; $i++, ($Exception = $Exception.InnerException)) { Write-Host ("$i" * 80) ; $Exception | Format-List * -Force | Out-String } }
PSMessageDetails :
Exception : System.Management.Automation.RuntimeException: Attempted to divide by zero. ---> System.DivideByZeroException: Attempted to divide by zero.
--- End of inner exception stack trace ---
at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject :
CategoryInfo : NotSpecified: (:) [], RuntimeException
FullyQualifiedErrorId : RuntimeException
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}
MyCommand :
BoundParameters : {}
UnboundArguments : {}
ScriptLineNumber : 1
OffsetInLine : 6
HistoryId : -1
ScriptName :
Line : try {1/0} catch { $Exception = $_; $Exception | Format-List * -Force | Out-String ; $Exception.InvocationInfo | Format-List * -Force | Out-String ; for ($i = 0; $Exception;
$i++, ($Exception = $Exception.InnerException)) { Write-Host ("$i" * 80) ; $Exception | Format-List * -Force | Out-String } }
PositionMessage : At line:1 char:6
+ try {1/0} catch { $Exception = $_; $Exception | Format-List * -Force ...
+ ~~~
PSScriptRoot :
PSCommandPath :
InvocationName :
PipelineLength : 0
PipelinePosition : 0
ExpectingInput : False
CommandOrigin : Internal
DisplayScriptPosition :
00000000000000000000000000000000000000000000000000000000000000000000000000000000
PSMessageDetails :
Exception : System.Management.Automation.RuntimeException: Attempted to divide by zero. ---> System.DivideByZeroException: Attempted to divide by zero.
--- End of inner exception stack trace ---
at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject :
CategoryInfo : NotSpecified: (:) [], RuntimeException
FullyQualifiedErrorId : RuntimeException
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}