捕获完整的异常消息 [英] Catching FULL exception message
问题描述
考虑:
Invoke-WebRequest $sumoApiURL -Headers @{"Content-Type"= "application/json"} -Credential $cred -WebSession $webRequestSession -Method post -Body $sumojson -ErrorAction Stop
这会引发以下异常:
我如何才能完全捕获它或至少过滤掉已存在同名资源."?
How can I catch it entirely or at least filter out the "A resource with the same name already exist."?
使用 $_.Exception.GetType().FullName
产生
System.Net.WebException
System.Net.WebException
和 $_.Exception.Message
给出
远程服务器返回错误:(400) Bad Request.
The remote server returned an error: (400) Bad Request.
推荐答案
PowerShell 中的错误和异常是结构化对象.您在控制台上看到的错误消息实际上是一个格式化消息,其中包含来自错误/异常对象的多个元素的信息.您可以像这样(重新)自己构建它:
Errors and exceptions in PowerShell are structured objects. The error message you see printed on the console is actually a formatted message with information from several elements of the error/exception object. You can (re-)construct it yourself like this:
$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
块中显示错误消息,您可以简单地回显当前对象变量(保存该点的错误):
If you just want the error message displayed in your catch
block you can simply echo the current object variable (which holds the error at that point):
try {
...
} catch {
$_
}
如果您需要彩色输出,请使用带有上述格式化字符串的 Write-Host
:
If you need colored output use Write-Host
with a formatted string as described above:
try {
...
} catch {
...
Write-Host -Foreground Red -Background Black ($formatstring -f $fields)
}
话虽如此,通常您不想只在异常处理程序中按原样显示错误消息(否则 -ErrorAction Stop
将毫无意义).结构化错误/异常对象为您提供了可用于更好地控制错误的附加信息.例如,你有 $_.Exception.HResult
和实际的错误号.$_.ScriptStackTrace
和 $_.Exception.StackTrace
,因此您可以在调试时显示堆栈跟踪.$_.Exception.InnerException
使您可以访问嵌套异常,这些异常通常包含有关错误的附加信息(顶级 PowerShell 错误可能有些通用).您可以使用以下内容展开这些嵌套异常:
With that said, usually you don't want to just display the error message as-is in an exception handler (otherwise the -ErrorAction Stop
would be pointless). The structured error/exception objects provide you with additional information that you can use for better error control. For instance you have $_.Exception.HResult
with the actual error number. $_.ScriptStackTrace
and $_.Exception.StackTrace
, so you can display stacktraces when debugging. $_.Exception.InnerException
gives you access to nested exceptions that often contain additional information about the error (top level PowerShell errors can be somewhat generic). You can unroll these nested exceptions with something like this:
$e = $_.Exception
$msg = $e.Message
while ($e.InnerException) {
$e = $e.InnerException
$msg += "`n" + $e.Message
}
$msg
在您的情况下,您要提取的信息似乎在 $_.ErrorDetails.Message
中.我不太清楚那里是否有对象或 JSON 字符串,但是您应该能够通过运行获得有关 $_.ErrorDetails
成员的类型和值的信息
In your case the information you want to extract seems to be in $_.ErrorDetails.Message
. It's not quite clear to me if you have an object or a JSON string there, but you should be able to get information about the types and values of the members of $_.ErrorDetails
by running
$_.ErrorDetails | Get-Member
$_.ErrorDetails | Format-List *
如果 $_.ErrorDetails.Message
是一个对象,你应该能够像这样获得消息字符串:
If $_.ErrorDetails.Message
is an object you should be able to obtain the message string like this:
$_.ErrorDetails.Message.message
否则需要先将 JSON 字符串转换为对象:
otherwise you need to convert the JSON string to an object first:
$_.ErrorDetails.Message | ConvertFrom-Json | Select-Object -Expand message
根据您正在处理的错误类型,特定类型的异常还可能包含有关手头问题的更具体信息.例如,在您的情况下,您有一个 WebException
,除了错误消息 ($_.Exception.Message
) 还包含来自服务器的实际响应:
Depending what kind of error you're handling, exceptions of particular types might also include more specific information about the problem at hand. In your case for instance you have a WebException
which in addition to the error message ($_.Exception.Message
) contains the actual response from the server:
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
由于并非所有异常都具有完全相同的属性集,因此您可能希望对特定异常使用特定的处理程序:
Since not all exceptions have the exact same set of properties you may want to use specific handlers for particular exceptions:
try {
...
} catch [System.ArgumentException] {
# handle argument exceptions
} catch [System.Net.WebException] {
# handle web exceptions
} catch {
# handle all other exceptions
}
如果你有一些操作不管是否发生错误都需要完成(清理任务,比如关闭套接字或数据库连接),你可以将它们放在异常之后的 finally
块中处理:
If you have operations that need to be done regardless of whether an error occured or not (cleanup tasks like closing a socket or a database connection) you can put them in a finally
block after the exception handling:
try {
...
} catch {
...
} finally {
# cleanup operations go here
}
这篇关于捕获完整的异常消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!