Condividi tramite


about_Try_Catch_Finally

Breve descrizione

Viene descritto come usare i blocchi try, catche finally per gestire gli errori di terminazione.

Descrizione lunga

Usare i blocchi try, catche finally per rispondere o gestire gli errori irreversibili negli script. L'istruzione trap può essere usata anche per gestire gli errori di terminazione negli script. Per altre informazioni, vedere about_Trap.

Un errore irreversibile impedisce l'esecuzione di un'istruzione. Se PowerShell non gestisce in qualche modo un errore irreversibile, PowerShell interrompe anche l'esecuzione della funzione o dello script usando la pipeline corrente. In altri linguaggi, ad esempio C#, gli errori di terminazione vengono definiti eccezioni.

Usare il blocco try per definire una sezione di uno script in cui si vuole che PowerShell monitori gli errori. Quando si verifica un errore all'interno del blocco try, l'errore viene prima salvato nella variabile automatica $Error. PowerShell cerca quindi un blocco di catch per gestire l'errore. Se l'istruzione try non dispone di un blocco di catch corrispondente, PowerShell continua a cercare un blocco catch appropriato o un'istruzione trap negli ambiti padre. Al termine di un blocco di catch o se non viene trovata alcuna istruzione catch o trap appropriata, viene eseguito il blocco finally. Se l'errore non può essere gestito, l'errore viene scritto nel flusso di errori.

Un blocco catch può includere comandi per tenere traccia dell'errore o per il ripristino del flusso previsto dello script. Un blocco catch può specificare quali tipi di errore intercetta. Un'istruzione try può includere più blocchi di catch per diversi tipi di errori.

Un blocco finally può essere usato per liberare tutte le risorse non più necessarie per lo script.

try, catche finally assomigliano alle parole chiave try, catche finally usate nel linguaggio di programmazione C#.

Sintassi

Un'istruzione try contiene un blocco try, zero o più blocchi di catch e zero o un blocco finally. Un'istruzione try deve avere almeno un blocco catch o un blocco finally.

Di seguito è illustrata la sintassi del blocco try:

try {<statement list>}

La parola chiave try è seguita da un elenco di istruzioni tra parentesi graffe. Se si verifica un errore irreversibile durante l'esecuzione delle istruzioni nell'elenco di istruzioni, lo script passa l'oggetto errore dal blocco try a un blocco di catch appropriato.

Di seguito è illustrata la sintassi del blocco catch:

catch [[<error type>][',' <error type>]*] {<statement list>}

I tipi di errore vengono visualizzati tra parentesi quadre. Le parentesi quadre più esterne indicano che l'elemento è facoltativo.

La parola chiave catch è seguita da un elenco facoltativo di specifiche del tipo di errore e da un elenco di istruzioni. Se si verifica un errore irreversibile nel blocco try, PowerShell cerca un blocco di catch appropriato. Se ne viene trovata una, vengono eseguite le istruzioni nel blocco catch.

Il blocco catch può specificare uno o più tipi di errore. Un tipo di errore è un'eccezione di Microsoft .NET Framework o un'eccezione derivata da un'eccezione di .NET Framework. Un blocco catch gestisce gli errori della classe di eccezione .NET Framework specificata o di qualsiasi classe che deriva dalla classe specificata.

Se un blocco catch specifica un tipo di errore, tale catch blocco gestisce tale tipo di errore. Se un blocco catch non specifica un tipo di errore, tale blocco catch gestisce qualsiasi errore rilevato nel blocco try. Un'istruzione try può includere più blocchi catch per i diversi tipi di errore specificati.

Di seguito è illustrata la sintassi del blocco finally:

finally {<statement list>}

La parola chiave finally è seguita da un elenco di istruzioni che viene eseguito ogni volta che viene eseguito lo script, anche se l'istruzione try è stata eseguita senza errori o viene rilevato un errore in un'istruzione catch.

Si noti che premendo CTRL+C arresta la pipeline. Gli oggetti inviati alla pipeline non verranno visualizzati come output. Pertanto, se si include un'istruzione da visualizzare, ad esempio "Finally block has run", non verrà visualizzata dopo aver premuto CTRL+C, anche se il blocco finally è stato eseguito.

Rilevamento degli errori

Lo script di esempio seguente mostra un blocco try con un blocco catch:

try { NonsenseString }
catch { "An error occurred." }

La parola chiave catch deve seguire immediatamente il blocco di try o un altro blocco di catch.

PowerShell non riconosce "NonsenseString" come cmdlet o un altro elemento. L'esecuzione di questo script restituisce il risultato seguente:

An error occurred.

Quando lo script rileva "NonsenseString", genera un errore irreversibile. Il blocco catch gestisce l'errore eseguendo l'elenco di istruzioni all'interno del blocco.

USO DI PIÙ ISTRUZIONI CATCH

Un'istruzione try può avere un numero qualsiasi di blocchi di catch. Ad esempio, lo script seguente include un blocco di try che scarica MyDoc.doce contiene due blocchi catch:

try {
    $wc = New-Object System.Net.WebClient
    $wc.DownloadFile("https://httpbin.org/MyDoc.doc","C:\temp\MyDoc.doc")
} catch [System.Net.WebException],[System.IO.IOException] {
    "Unable to download MyDoc.doc from https://httpbin.org."
} catch {
    "An error occurred that could not be resolved."
}

Il primo blocco catch gestisce gli errori dei tipi System.Net.WebException e System.IO.IOException. Il secondo blocco catch non specifica un tipo di errore. Il secondo blocco catch gestisce eventuali altri errori irreversibili che si verificano.

PowerShell corrisponde ai tipi di errore in base all'ereditarietà. Un blocco catch gestisce gli errori della classe di eccezione .NET Framework specificata o di qualsiasi classe che deriva dalla classe specificata. L'esempio seguente contiene un blocco catch che rileva un errore "Comando non trovato":

catch [System.Management.Automation.CommandNotFoundException] {
    "Inherited Exception"
}

Il tipo di errore specificato, CommandNotFoundException, eredita dal tipo System.SystemException. L'esempio seguente rileva anche un errore Command Not Found:

catch [System.SystemException] {"Base Exception" }

Questo blocco catch gestisce l'errore "Comando non trovato" e altri errori che ereditano dal tipo SystemException.

Se si specifica una classe di errore e una delle relative classi derivate, posizionare il blocco catch per la classe derivata prima del blocco catch per la classe generale.

Nota

PowerShell esegue il wrapping di tutte le eccezioni in un tipo di RuntimeException. Pertanto, specificando il tipo di errore System.Management.Automation.RuntimeException si comporta come un blocco catch non qualificato.

Uso di trappole in un tentativo catch

Quando si verifica un errore irreversibile in un blocco try con un trap definito all'interno del blocco try, anche se è presente un blocco di catch corrispondente, l'istruzione trap assume il controllo.

Se un trap esiste in un blocco superiore a quello di trye non esiste alcun blocco catch corrispondente all'interno dell'ambito corrente, il trap assumerà il controllo, anche se un ambito padre ha un blocco di catch corrispondente.

Accesso alle informazioni sulle eccezioni

All'interno di un catch blocco, è possibile accedere all'errore corrente usando la $_ variabile o $PSItem automatica. L'oggetto è di tipo ErrorRecord.

try { NonsenseString }
catch {
    Write-Host "An error occurred:"
    Write-Host $_
}

L'esecuzione di questo script restituisce il risultato seguente:

An Error occurred:
The term 'NonsenseString' 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.

È possibile accedere ad altre proprietà, ad esempio ScriptStackTrace, Exceptione ErrorDetails. Ad esempio, se lo script viene modificato nel modo seguente:

try { NonsenseString }
catch {
    Write-Host "An error occurred:"
    Write-Host $_.ScriptStackTrace
}

Il risultato sarà simile al seguente:

An Error occurred:
at <ScriptBlock>, <No file>: line 2

Liberare le risorse usando finally

Per liberare le risorse usate da uno script, aggiungere un blocco di finally dopo i blocchi try e catch. Le istruzioni di blocco finally vengono eseguite indipendentemente dal fatto che il blocco try riscontri un errore irreversibile. PowerShell esegue il blocco finally prima che lo script termini o prima che il blocco corrente esegua l'ambito.

Viene eseguito un blocco di finally anche se si usa CTRL+C per arrestare lo script. Un blocco finally viene eseguito anche se una parola chiave exit arresta lo script dall'interno di un blocco catch.

Nell'esempio seguente il blocco try tenta di scaricare un file nella cartella C:\temp. Il catch blocca la gestione degli errori che si verificano durante il download. Il blocco finally elimina l'oggetto WebClient e rimuove il file temporaneo, se esistente.

try {
    $wc = New-Object System.Net.WebClient
    $tempFile = "C:\temp\MyDoc.doc"
    $wc.DownloadFile("https://httpbin.org/MyDoc.doc",$tempFile)
} catch [System.Net.WebException],[System.IO.IOException] {
    "Unable to download MyDoc.doc from https://httpbin.org."
} catch {
    "An error occurred that could not be resolved."
} finally {
    $wc.Dispose()
    if (Test-Path $tempPath) { Remove-Item $tempFile }
}

Vedere anche