Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Descripción breve
Describe los tipos de errores en PowerShell y los mecanismos para controlarlos.
Descripción larga
PowerShell distingue tres categorías de errores:
- Errores de no terminación
- Errores de terminación de instrucciones
- Errores de terminación de script
Comprender la distinción es esencial para escribir scripts y módulos confiables, ya que cada categoría tiene un comportamiento predeterminado diferente y requiere diferentes técnicas de control.
Además, los programas externos (nativos) notifican errores a través de códigos de salida, que PowerShell realiza un seguimiento por separado de su propio sistema de errores.
Tipos de errores
Errores de no terminación
Un error de no terminación notifica un problema, pero no detiene la canalización. El comando continúa procesando los objetos de entrada posteriores. Los errores de no terminación se generan mediante:
- El
Write-Errorcmdlet - Método
$PSCmdlet.WriteError()en funciones avanzadas - Cmdlets que encuentran errores recuperables en objetos de entrada individuales
De forma predeterminada, PowerShell muestra el mensaje de error y continúa la ejecución.
# Non-terminating error: the pipeline continues after the failure
'file1.txt', 'noSuchFile.txt', 'file3.txt' | ForEach-Object {
Get-Content $_ -ErrorAction Continue
}
En este ejemplo, notifica un error de no terminación para noSuchFile.txt y, a continuación, Get-Content continúa procesando file3.txt.
Los errores de no terminación no se desencadenan catch o trap de forma predeterminada.
Errores de terminación de instrucciones
Un error de terminación de instrucción impide que se ejecute la instrucción actual (canalización), pero la ejecución continúa en la siguiente instrucción del script. Los errores de terminación de instrucciones se generan mediante:
- Método
$PSCmdlet.ThrowTerminatingError()en funciones avanzadas y cmdlets compilados - Errores de motor, como
CommandNotFoundException(llamar a un comando que no existe) yParameterBindingException(argumentos de parámetro no válidos) - Llamadas al método .NET que producen excepciones, como
[int]::Parse('abc')
# Statement-terminating error: Get-Item fails, but the next statement runs
Get-Item -Path 'C:\NoSuchFile.txt'
Write-Output 'This still runs'
Los errores de terminación de instrucciones se pueden detectar mediante try/catch y trap.
Nota:
.ThrowTerminatingError() no consulta el -ErrorAction parámetro (excepto el Break valor , que especifica el depurador). Sin embargo, $ErrorActionPreferencese aplica a los errores de terminación de instrucciones a través del controlador de nivel de instrucción del motor. Por ejemplo, $ErrorActionPreference = 'SilentlyContinue' puede suprimir un error de terminación de instrucción para que el script continúe en la instrucción siguiente. El -ErrorAction parámetro no puede hacerlo. Para obtener más información, consulte La $ErrorActionPreference asimetría.
Errores de terminación de script
Un error de terminación de script desenreda toda la pila de llamadas. La ejecución se detiene completamente a menos que una try/catch instrucción o trap bloque detecte el error. Los errores de terminación de script se generan mediante:
- La palabra clave
throw. - Análisis de errores (errores de sintaxis que impiden que el script se compile)
- Errores de no terminación escalados por
-ErrorAction Stopo$ErrorActionPreference = 'Stop'en contextos no avanzados. Para obtener más información, consulte Funcionamiento de la escalación. - Ciertos errores críticos del motor
# Script-terminating error: throw unwinds the call stack
function Test-Throw {
throw 'Critical failure'
Write-Output 'This never runs'
}
Test-Throw
Write-Output 'This never runs either (unless caught)'
La throw palabra clave genera un error de terminación de script de forma predeterminada. Sin embargo, $ErrorActionPreferencepuede suprimirse throw cuando se establece en SilentlyContinue o Ignore. Al llamar a una función avanzada con -ErrorAction SilentlyContinue, el parámetro se traduce en un valor local $ErrorActionPreference de ámbito, por lo que también suprime throw dentro de esa función.
Nota:
Incluso con $ErrorActionPreference = 'Ignore', un throw objeto que se suprime todavía registra una entrada en $Error. El Ignore valor solo impide $Error la grabación de errores de no terminación .
Importante
Los términos de terminación de instrucciones y terminación de script describen el ámbito del impacto, no la gravedad del error. Un error de terminación de instrucción detiene una instrucción. Un error de terminación de script detiene todo el script y sus autores de llamada. Ambos pueden ser capturados por try/catch.
Errores de programa externo
Los programas externos (nativos) no participan directamente en el sistema de errores de PowerShell. Notifican un error a través de un código de salida distinto de cero, que PowerShell almacena en la $LASTEXITCODE variable automática.
git clone https://example.com/nonexistent.git 2>$null
if ($LASTEXITCODE -ne 0) {
Write-Error "git failed with exit code $LASTEXITCODE"
}
De forma predeterminada, un código de salida distinto de cero de un programa nativo:
- Establece en
$?$false -
No genera un
ErrorRecorden$Error -
No desencadena
catchnitrap
PowerShell 7.3 agregó la variable $PSNativeCommandUseErrorActionPreferencede preferencia experimental , que se convirtió en una característica estable en la versión 7.4. Cuando establece esta variable $trueen , hace que un código de salida distinto de cero emita un error de no terminación cuyo mensaje indique el código de salida específico (a NativeCommandExitException). Este error respeta $ErrorActionPreference, por lo que establecerlo para Stop promover el error a un error de terminación de script que se puede detectar con/trycatch .
Variables de estado de error
PowerShell mantiene varias variables automáticas que reflejan el estado de error actual.
$?
Contiene $true si la última operación se realizó correctamente y $false si produjo algún error (sin terminación o terminación). En el caso de los comandos nativos, $? se establece en función del código de salida: $true para el código 0de salida ; $false de lo contrario, .
Get-Item -Path 'C:\NoSuchFile.txt' 2>$null
$? # False
$Error
que ArrayList almacena los registros de error más recientes, con el error más reciente en el índice 0. La lista contiene hasta $MaximumErrorCount entradas (valor predeterminado 256).
Todos los errores de terminación se agregan a $Error. Para finalizar los errores, Ignore suprime la presentación, pero sigue registrando el error en $Error. Todas las operaciones de no terminación se agregan a $Error a menos -ErrorAction Ignore que se usen en errores de no terminación, lo que impide la visualización y la grabación.
$LASTEXITCODE
Contiene el código de salida del último programa nativo que se ejecutó. Un valor de 0 convencionalmente indica que se ha realizado correctamente. Cualquier valor distinto de cero indica un error. Esta variable no se ve afectada por errores de cmdlet de PowerShell.
Control del comportamiento del error
Parámetro -ErrorAction común
El -ErrorAction parámetro común invalida $ErrorActionPreference para un solo comando. Controla cómo Responde PowerShell a errores de no terminación desde ese comando.
| Importancia | Comportamiento |
|---|---|
Continue |
Mostrar el error y continuar (valor predeterminado) |
SilentlyContinue |
Suprimir la visualización, agregar a $Error, continuar |
Ignore |
Suprimir la visualización y no agregar a $Error |
Stop |
Escalado a un error de terminación (consulte Funcionamiento de la escalación) |
Inquire |
Pedir al usuario una decisión |
Break |
Escriba el depurador. |
-ErrorAction no cambia el comportamiento de los errores generados por $PSCmdlet.ThrowTerminatingError(). Esos errores siempre son terminación de instrucciones independientemente de la preferencia del autor de la llamada.
Variable $ErrorActionPreference
La $ErrorActionPreference variable de preferencia se aplica a todos los comandos del ámbito actual y los ámbitos secundarios. Acepta los mismos valores que -ErrorAction.
$ErrorActionPreference = 'Stop'
# All non-terminating errors in this scope now become terminating
Write-Error 'This now throws' # Generates ActionPreferenceStopException
Cuando -ErrorAction se especifica en un comando, tiene prioridad sobre $ErrorActionPreference ese comando.
Funcionamiento de la escalación
Cuando -ErrorAction Stop o $ErrorActionPreference = 'Stop' está en vigor, PowerShell convierte los errores de no terminación en errores de terminación mediante el siguiente mecanismo:
- Un cmdlet llama
WriteError()internamente para emitir un error de no terminación. - El motor comprueba la preferencia efectiva
ErrorActiondel comando. - Dado que la preferencia es
Stop, el motor crea unActionPreferenceStopExceptionque encapsula el registro de error original. - Si se detecta mediante
catch, se puede acceder a la información de error original a través de$_.Exception.ErrorRecord.
El ámbito del error escalado depende del contexto:
- En scripts, funciones o bloques de scripts no avanzados , la configuración
$ErrorActionPreference = 'Stop'se escala a un error de terminación de script . El error propaga la pila de llamadas. - En funciones avanzadas y bloques de script (aquellos con
[CmdletBinding()]), el error permanece terminado por instrucciones. La ejecución continúa en la siguiente instrucción después de la llamada. - Pasar
-ErrorAction Stopa una función avanzada tiene el mismo efecto que establecer$ErrorActionPreference = 'Stop'dentro de ella, ya que-ErrorActionse traduce en un valor local$ErrorActionPreferencede ámbito.
Ejemplos de escalado
NO avanzado: terminación de script ('after' no imprime)
& { param() $ErrorActionPreference = 'Stop' Get-Item 'NoSuchPath' } 2>$null 'after'ADVANCED: terminación de instrucciones ('after' DOES print)
& { [CmdletBinding()] param() $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' } 2>$null 'after'Sin
-ErrorAction Stop: sin terminación, catch no se ejecutatry { Write-Error 'This is non-terminating' Write-Output 'Execution continues' } catch { Write-Output "Caught: $_" # Not reached }Con
-ErrorAction Stop: escalado a terminacióntry { Write-Error 'This becomes terminating' -ErrorAction Stop } catch { Write-Output "Caught: $_" # Reached }
El tipo de excepción original puede detectar errores escalados. El motor desencapsula para ActionPreferenceStopException buscar la excepción subyacente:
try {
Get-Item -Path 'C:\NoSuchFile.txt' -ErrorAction Stop
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Output "File not found: $($_.Exception.Message)"
}
La $ErrorActionPreference asimetría
El -ErrorAction parámetro y la $ErrorActionPreference variable se comportan de forma diferente con errores de terminación. Es importante comprender esta asimetría:
-ErrorActionsolo afecta a los errores de no terminación . Cuando un cmdlet llama a$PSCmdlet.ThrowTerminatingError(), se omite el-ErrorActionparámetro (excepto paraBreak, que entra en el depurador). El error siempre se produce.$ErrorActionPreferenceafecta tanto a errores de no terminación como de terminación de instrucciones. El controlador de errores de nivel de instrucción del motor lee$ErrorActionPreference(no el-ErrorActionparámetro) y puede suprimir un error de terminación de instrucción cuando el valor esSilentlyContinueoIgnore.
function Test-Asymmetry {
[CmdletBinding()]
param()
$er = [System.Management.Automation.ErrorRecord]::new(
[System.InvalidOperationException]::new('test error'),
'TestError',
[System.Management.Automation.ErrorCategory]::InvalidOperation,
$null
)
$PSCmdlet.ThrowTerminatingError($er)
}
# -ErrorAction SilentlyContinue does NOT suppress the error:
Test-Asymmetry -ErrorAction SilentlyContinue # Error is still thrown
# $ErrorActionPreference DOES suppress the error:
$ErrorActionPreference = 'SilentlyContinue'
Test-Asymmetry # Error is silently suppressed, script continues
$ErrorActionPreference = 'Continue'
Importante
$ErrorActionPreference no puede suprimir los errores que se han SuppressPromptInInterpreter establecido en true. Siempre se propagan independientemente de la variable de preferencia. Entre los ejemplos de este tipo de error se incluyen:
-
ActionPreferenceStopExceptiondesde la-ErrorAction Stopescalación - Errores dentro de los métodos de clase de PowerShell
PipelineStoppedException
Manejo de errores
try/catch/finally
Use try/catch/finally para controlar los errores de terminación de instrucciones y de terminación de scripts. Cuando se produce un error dentro de un try bloque, PowerShell busca un bloque coincidente catch . El finally bloque siempre se ejecuta, independientemente de si se produjo o no un error.
try {
$result = Get-Content -Path 'data.txt' -ErrorAction Stop
}
catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning 'Data file not found, using defaults.'
$result = 'default'
}
catch {
Write-Warning "Unexpected error: $_"
}
finally {
Write-Verbose 'Cleanup complete.' -Verbose
}
Dentro de un try bloque, el motor establece una marca interna que provoca errores de no terminación escalados por -ErrorAction Stop o $ErrorActionPreference = 'Stop' para propagarse al catch bloque. Este comportamiento está diseñado, no un caso especial.
Para obtener información completa sobre la sintaxis, consulte about_Try_Catch_Finally.
trap
La trap instrucción controla los errores de terminación en el nivel de ámbito. Cuando se produce un error en cualquier parte del ámbito envolvente, el trap bloque se ejecuta.
-
Valor predeterminado (no
breakocontinue): el error se muestra y la ejecución continúa en la siguiente instrucción después de la que provocó el error. -
continueen la captura: suprime el mensaje de error y se reanuda en la siguiente instrucción. -
breaken la captura: el error se propaga al ámbito primario.
trap [System.Management.Automation.CommandNotFoundException] {
Write-Warning "Command not found: $($_.TargetObject)"
continue
}
NonsenseCommand # Trap fires, execution continues
Write-Output 'This runs because the trap used continue'
Para obtener información completa sobre la sintaxis, consulte about_Trap.
Notificación de errores en funciones y scripts
Al escribir funciones y scripts, elija el mecanismo de informes de errores que coincida con la gravedad del error.
Sin terminación: use Write-Error
Use Write-Error cuando la función pueda continuar procesando otra entrada. Esto es adecuado para las funciones de canalización que procesan varios objetos y detectan errores en elementos individuales.
function Test-Path-Safe {
[CmdletBinding()]
param([Parameter(ValueFromPipeline)][string]$Path)
process {
if (-not (Test-Path $Path)) {
Write-Error "Path not found: $Path"
return
}
$Path
}
}
Nota:
En funciones avanzadas (aquellas con [CmdletBinding()]), use $PSCmdlet.WriteError() en lugar de para asegurarse de Write-Error que $? está correctamente establecido $false en en el ámbito del autor de la llamada. El Write-Error cmdlet no siempre se establece $? correctamente.
Terminación de instrucciones: uso $PSCmdlet.ThrowTerminatingError()
Use $PSCmdlet.ThrowTerminatingError() cuando la función no pueda continuar en absoluto, pero el autor de la llamada debe decidir cómo controlar el error. Este es el enfoque recomendado en funciones avanzadas.
function Get-Config {
[CmdletBinding()]
param([string]$Path)
if (-not (Test-Path $Path)) {
$er = [System.Management.Automation.ErrorRecord]::new(
[System.IO.FileNotFoundException]::new("Config file not found: $Path"),
'ConfigNotFound',
[System.Management.Automation.ErrorCategory]::ObjectNotFound,
$Path
)
$PSCmdlet.ThrowTerminatingError($er)
}
Get-Content $Path | ConvertFrom-Json
}
Una vez que el error deja la función, el autor de la llamada la trata como un error de no terminación de forma predeterminada. El autor de la llamada puede escalarlo con -ErrorAction Stop.
Terminación de script: uso throw
Use throw cuando la recuperación no sea posible y el script completo debe detenerse.
$config = Get-Content 'config.json' -ErrorAction SilentlyContinue |
ConvertFrom-Json
if (-not $config) {
throw 'Cannot proceed without a valid configuration file.'
}
Mecanismo que se va a usar
- Al procesar varias entradas en las que algunos pueden producir errores, use
Write-Erroro$PSCmdlet.WriteError(). - Si la función no puede continuar, use
$PSCmdlet.ThrowTerminatingError()y deje que el autor de la llamada decida cómo controlarla. - Si todo el script debe detenerse inmediatamente, use
throw.
Resumen de los tipos de error
En las tablas siguientes se resumen las propiedades y comportamientos de los distintos tipos de error en PowerShell.
Error de no terminación
Los errores de no terminación se pueden generar mediante Write-Error o $PSCmdlet.WriteError().
| Atributo | Descripción |
|---|---|
| Ámbito de impacto | Continúa la canalización |
Atrapado por catch |
No (a menos que se escale) |
Atrapado por trap |
No (a menos que se escale) |
Agregado a $Error |
Sí (a menos Ignoreque ) |
Establece en $?$false |
Sí |
Afectado por -ErrorAction |
Sí |
Afectado por $ErrorActionPreference |
Sí |
Error de terminación de instrucciones
Los errores de terminación de instrucciones se pueden generar mediante ThrowTerminatingError(), errores del motor, excepciones de método de .NET o -ErrorAction Stop en contextos avanzados.
| Atributo | Descripción |
|---|---|
| Ámbito de impacto | La instrucción actual se detiene; script continues |
Atrapado por catch |
Sí |
Atrapado por trap |
Sí |
Agregado a $Error |
Sí |
Establece en $?$false |
Sí |
Afectado por -ErrorAction |
No (Break solo) |
Afectado por $ErrorActionPreference |
Sí (puede suprimir) |
Error de terminación de script
Los errores de terminación de scripts se pueden generar mediante throw, analizar errores o -ErrorAction Stop en contextos no avanzados.
| Atributo | Descripción |
|---|---|
| Ámbito de impacto | Desenredado de pila de llamadas |
Atrapado por catch |
Sí |
Atrapado por trap |
Sí |
Agregado a $Error |
Sí |
Establece en $?$false |
Sí |
Afectado por -ErrorAction |
No |
Afectado por $ErrorActionPreference |
throw: Sí (puede suprimir) |
Afectado por $ErrorActionPreference |
Escalado: depende del contexto |