about_Try_Catch_Finally
Descripción breve
Describe cómo usar los try
bloques , catch
y finally
para controlar los errores de terminación.
Descripción larga
Use try
bloques , catch
y finally
para responder o controlar errores de terminación en scripts. La Trap
instrucción también se puede usar para controlar los errores de terminación en los scripts. Para obtener más información, consulte about_Trap.
Un error de terminación impide que se ejecute una instrucción. Si PowerShell no controla un error de terminación de alguna manera, PowerShell también deja de ejecutar la función o script mediante la canalización actual. En otros lenguajes, como C#, los errores de terminación se conocen como excepciones.
Use el try
bloque para definir una sección de un script en el que desea que PowerShell supervise si hay errores. Cuando se produce un error dentro del try
bloque, el error se guarda primero en la $Error
variable automática. A continuación, PowerShell busca un catch
bloque para controlar el error. Si la try
instrucción no tiene un bloque coincidentecatch
, PowerShell continúa buscando un bloque o catch
instrucción adecuado Trap
en los ámbitos primarios. Una vez completado un catch
bloque o si no se encuentra ninguna instrucción o catch
bloque adecuadoTrap
, se ejecuta el finally
bloque. Si no se puede controlar el error, el error se escribe en la secuencia de errores.
Un catch
bloque puede incluir comandos para realizar el seguimiento del error o para recuperar el flujo esperado del script. Un catch
bloque puede especificar qué tipos de error detecta. Una try
instrucción puede incluir varios catch
bloques para diferentes tipos de errores.
Un finally
bloque se puede usar para liberar los recursos que ya no necesite el script.
try
, catch
y finally
se asemejan a las try
palabras clave , catch
y finally
usadas en el lenguaje de programación de C#.
Sintaxis
Una try
instrucción contiene un try
bloque, cero o más catch
bloques y cero o un finally
bloque. Una try
instrucción debe tener al menos un catch
bloque o un finally
bloque.
A continuación se muestra la sintaxis de try
bloque:
try {<statement list>}
La try
palabra clave va seguida de una lista de instrucciones entre llaves. Si se produce un error de terminación mientras se ejecutan las instrucciones de la lista de instrucciones, el script pasa el objeto de error del try
bloque a un bloque adecuado catch
.
A continuación se muestra la sintaxis de catch
bloque:
catch [[<error type>][',' <error type>]*] {<statement list>}
Los tipos de error aparecen entre corchetes. Los corchetes más externos indican que el elemento es opcional.
La catch
palabra clave va seguida de una lista opcional de especificaciones de tipo de error y una lista de instrucciones. Si se produce un error de terminación en el try
bloque, PowerShell busca un bloque adecuado catch
. Si se encuentra una, se ejecutan las instrucciones del catch
bloque .
El catch
bloque puede especificar uno o varios tipos de error. Un tipo de error es una excepción de Microsoft .NET Framework o una excepción derivada de una excepción de .NET Framework. Un catch
bloque controla los errores de la clase de excepción de .NET Framework especificada o de cualquier clase que derive de la clase especificada.
Si un catch
bloque especifica un tipo de error, ese catch
bloque controla ese tipo de error. Si un catch
bloque no especifica un tipo de error, ese catch
bloque controla cualquier error encontrado en el try
bloque. Una try
instrucción puede incluir varios catch
bloques para los distintos tipos de error especificados.
A continuación se muestra la sintaxis de finally
bloque:
finally {<statement list>}
La finally
palabra clave va seguida de una lista de instrucciones que se ejecuta cada vez que se ejecuta el script, incluso si la try
instrucción se ejecutó sin error o se detectó un error en una catch
instrucción .
Tenga en cuenta que al presionar CTRL+C se detiene la canalización. Los objetos que se envían a la canalización no se mostrarán como salida. Por lo tanto, si incluye una instrucción que se va a mostrar, como "Finally block has run", no se mostrará después de presionar CTRL+C, incluso si se ejecutó el finally
bloque.
Almacenamiento en caché de los errores
El siguiente script de ejemplo muestra un try
bloque con un catch
bloque:
try { NonsenseString }
catch { "An error occurred." }
La catch
palabra clave debe seguir inmediatamente el try
bloque u otro catch
bloque.
PowerShell no reconoce "NonsenseString" como cmdlet u otro elemento. Al ejecutar este script, se devuelve el siguiente resultado:
An error occurred.
Cuando el script encuentra "NonsenseString", provoca un error de terminación. El catch
bloque controla el error ejecutando la lista de instrucciones dentro del bloque .
Uso de varias instrucciones catch
Una try
instrucción puede tener cualquier número de catch
bloques. Por ejemplo, el siguiente script tiene un try
bloque que descarga MyDoc.doc
y contiene dos catch
bloques:
try {
$wc = New-Object System.Net.WebClient
$wc.DownloadFile("http://www.contoso.com/MyDoc.doc","c:\temp\MyDoc.doc")
} catch [System.Net.WebException],[System.IO.IOException] {
"Unable to download MyDoc.doc from http://www.contoso.com."
} catch {
"An error occurred that could not be resolved."
}
El primer catch
bloque controla los errores de los tipos System.Net.WebException y System.IO.IOException . El segundo catch
bloque no especifica un tipo de error. El segundo catch
bloque controla cualquier otro error de terminación que se produzca.
PowerShell coincide con los tipos de error por herencia. Un catch
bloque controla los errores de la clase de excepción de .NET Framework especificada o de cualquier clase que derive de la clase especificada. El ejemplo siguiente contiene un catch
bloque que detecta un error "Comando no encontrado":
catch [System.Management.Automation.CommandNotFoundException] {
"Inherited Exception"
}
El tipo de error especificado, CommandNotFoundException, hereda del tipo System.SystemException . En el ejemplo siguiente también se detecta un error Command Not Found:
catch [System.SystemException] {"Base Exception" }
Este catch
bloque controla el error "Comando no encontrado" y otros errores que heredan del tipo SystemException .
Si especifica una clase de error y una de sus clases derivadas, coloque el catch
bloque para la clase derivada antes del catch
bloque de la clase general.
Nota:
PowerShell encapsula todas las excepciones en un tipo RuntimeException . Por lo tanto, especificar el tipo de error System.Management.Automation.RuntimeException se comporta igual que un bloque catch no completo.
Uso de capturas en un Try Catch
Cuando se produce un error de terminación en un try
bloque con un Trap
definido dentro del try
bloque, aunque haya un bloque coincidente catch
, la Trap
instrucción toma el control.
Si existe en Trap
un bloque superior al try
, y no hay ningún bloque coincidente dentro del ámbito actual, tomará el catch
control, incluso si algún ámbito primario tiene un bloque coincidente Trap
catch
.
Acceso a la información de excepciones
Dentro de un catch
bloque, se puede acceder al error actual mediante $_
, que también se conoce como $PSItem
. El objeto es de tipo ErrorRecord.
try { NonsenseString }
catch {
Write-Host "An error occurred:"
Write-Host $_
}
Al ejecutar este script, se devuelve el siguiente resultado:
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.
Hay propiedades adicionales a las que se puede acceder, como ScriptStackTrace, Exception y ErrorDetails. Por ejemplo, si cambiamos el script a lo siguiente:
try { NonsenseString }
catch {
Write-Host "An error occurred:"
Write-Host $_.ScriptStackTrace
}
El resultado será similar a:
An Error occurred:
at <ScriptBlock>, <No file>: line 2
Liberar recursos mediante finalmente
Para liberar recursos usados por un script, agregue un finally
bloque después de los try
bloques y catch
. Las finally
instrucciones block se ejecutan independientemente de si el try
bloque encuentra un error de terminación. PowerShell ejecuta el finally
bloque antes de que finalice el script o antes de que el bloque actual salga del ámbito.
Un finally
bloque se ejecuta incluso si usa CTRL+C para detener el script. Un finally
bloque también se ejecuta si una palabra clave Exit detiene el script desde un catch
bloque.
En el ejemplo siguiente, el bloque try
intenta descargar un archivo en la carpeta c:\temp
. Los bloques catch
controlan los errores que se producen durante la descarga. El bloque finally
elimina el objeto WebClient
y quita el archivo temporal si existe.
try {
$wc = New-Object System.Net.WebClient
$tempFile = "c:\temp\MyDoc.doc"
$wc.DownloadFile("http://www.contoso.com/MyDoc.doc",$tempFile)
} catch [System.Net.WebException],[System.IO.IOException] {
"Unable to download MyDoc.doc from http://www.contoso.com."
} catch {
"An error occurred that could not be resolved."
} finally {
$wc.Dispose()
if (Test-Path $tempPath) { Remove-item $tempFile }
}