errori e le eccezioni in PowerShell sono oggetti strutturati. Il messaggio di errore che vedi stampato sulla console è in realtà un messaggio formattato con informazioni provenienti da diversi elementi dell'oggetto error/exception. È possibile (ri) costruire voi stessi in questo modo:
$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
Se si desidera solo il messaggio di errore visualizzato nel catch
blocco si può semplicemente eco la variabile oggetto corrente (che detiene l'errore in quel punto):
try {
...
} catch {
$_
}
Se avete bisogno di utilizzare l'uscita di colore Write-Host
con una stringa formattata come sopra descritto:
try {
...
} catch {
...
Write-Host -Foreground Red -Background Black ($formatstring -f $fields)
}
detto questo, di solito don Non voglio semplicemente visualizzare il messaggio di errore così com'è in un gestore di eccezioni (altrimenti lo -ErrorAction Stop
sarebbe inutile). Gli oggetti strutturati di errore/eccezione forniscono informazioni aggiuntive che è possibile utilizzare per un migliore controllo degli errori. Ad esempio hai $_.Exception.HResult
con il numero di errore effettivo. $_.ScriptStackTrace
e $_.Exception.StackTrace
, quindi è possibile visualizzare gli stacktraces durante il debug. $_.Exception.InnerException
consente di accedere a eccezioni nidificate che spesso contengono informazioni aggiuntive sull'errore (gli errori di PowerShell di livello superiore possono essere piuttosto generici). È possibile svolgere queste eccezioni nidificate con qualcosa di simile:
$e = $_.Exception
$msg = $e.Message
while ($e.InnerException) {
$e = $e.InnerException
$msg += "`n" + $e.Message
}
$msg
Nel tuo caso le informazioni che si desidera estrarre sembra essere in $_.ErrorDetails.Message
.Non è del tutto chiaro per me se si dispone di un oggetto o di una stringa JSON lì, ma si dovrebbe essere in grado di ottenere informazioni sui tipi ei valori dei membri del $_.ErrorDetails
eseguendo
$_.ErrorDetails | Get-Member
$_.ErrorDetails | Format-List *
Se $_.ErrorDetails.Message
è un oggetto che si dovrebbe essere in grado di ottenere la stringa messaggio come questo:
$_.ErrorDetails.Message.message
altrimenti è necessario per convertire la stringa JSON a un oggetto prima:
$_.ErrorDetails.Message | ConvertFrom-Json | Select-Object -Expand message
In base al tipo di errore che si sta trattando, le eccezioni di determinati tipi potrebbero anche includere informazioni più specifiche sul problema in questione. Nel tuo caso, per esempio si dispone di un WebException
che oltre al messaggio di errore ($_.Exception.Message
) contiene la risposta effettiva dal 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;}
che fornisce le informazioni in questo modo:
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
Dal non tutte le eccezioni hanno lo stesso esatto insieme di proprietà si consiglia di utilizzare i gestori specifici per particolari eccezioni:
try {
...
} catch [System.ArgumentException] {
# handle argument exceptions
} catch [System.Net.WebException] {
# handle web exceptions
} catch {
# handle all other exceptions
}
Se si dispone di operazioni che devono essere fatte indipendentemente dal fatto che un errore si è verificato o meno (operazioni di pulitura, come la chiusura di una presa di corrente o di una connessione al database) si possono inserire in un blocco finally
dopo la gestione delle eccezioni:
try {
...
} catch {
...
} finally {
# cleanup operations go here
}
I ho già trovato la risposta, ma questo è molto più dettagliato. Saluti. – JustAGuy
Grazie per la spiegazione approfondita. Molto utile. –