From e836f5681400531921c8f97af87d4bca3ea04c56 Mon Sep 17 00:00:00 2001 From: SufficientDaikon Date: Thu, 26 Mar 2026 15:24:22 +0200 Subject: [PATCH 01/10] Add about_Error_Handling and fix error terminology across docs Create a comprehensive about_Error_Handling reference topic that documents PowerShell's three error categories: non-terminating, statement-terminating, and script-terminating errors. Correct false claims in about_CommonParameters and about_Preference_Variables that state -ErrorAction and $ErrorActionPreference have "no effect on terminating errors." Update about_Try_Catch_Finally, about_Throw, about_Trap, and everything-about-exceptions to use precise terminology consistent with existing usage in about_Calculated_Properties, about_Pipeline_Chain_Operators, and about_Pwsh. Fixes MicrosoftDocs/PowerShell-Docs#1583 --- .../About/about_CommonParameters.md | 21 +- .../About/about_Error_Handling.md | 409 ++++++++++++++++++ .../About/about_Preference_Variables.md | 13 +- .../About/about_Throw.md | 15 +- .../About/about_Trap.md | 18 +- .../About/about_Try_Catch_Finally.md | 26 +- .../deep-dives/everything-about-exceptions.md | 49 ++- 7 files changed, 501 insertions(+), 50 deletions(-) create mode 100644 reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md index 4439bc733c1e..e433623c9fe8 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md @@ -105,8 +105,9 @@ the display of debugging messages when `$DebugPreference` isn't ### -ErrorAction Determines how the cmdlet responds to a non-terminating error from the command. -This parameter works only when the command generates a non-terminating error, -such as those from the `Write-Error` cmdlet. +This parameter overrides the value of the `$ErrorActionPreference` variable for +non-terminating errors generated by the command, such as those from the +`Write-Error` cmdlet. ```yaml Type: ActionPreference @@ -124,9 +125,12 @@ variable for the current command. Because the default value of the `$ErrorActionPreference` variable is `Continue`, error messages are displayed and execution continues unless you use the `ErrorAction` parameter. -The `ErrorAction` parameter has no effect on terminating errors (such as -missing data, parameters that aren't valid, or insufficient permissions) that -prevent a command from completing successfully. +The `-ErrorAction` parameter doesn't prevent statement-terminating errors +(such as missing data, parameters that aren't valid, or insufficient +permissions) from stopping the current statement. However, when set to `Stop`, +it escalates non-terminating errors to statement-terminating errors, making +them catchable by `try/catch`. For more information about error categories, see +[about_Error_Handling][15]. - `Break` Enters the debugger when an error occurs or an exception is raised. - `Continue` displays the error message and continues executing the command. @@ -139,7 +143,10 @@ prevent a command from completing successfully. continuing execution. This value is rarely used. - `SilentlyContinue` suppresses the error message and continues executing the command. -- `Stop` displays the error message and stops executing the command. +- `Stop` displays the error message and stops executing the command. The + `Stop` value escalates the non-terminating error to a statement-terminating + error by generating an `ActionPreferenceStopException`. The error can then + be caught by a `try/catch` block or `trap` statement. - `Suspend` is only available for workflows which aren't supported in PowerShell 6 and beyond. @@ -817,6 +824,7 @@ Mode LastWriteTime Length Name - [about_Preference_Variables][03] +- [about_Error_Handling][15] - [`Write-Debug`][11] - [`Write-Error`][12] - [`Write-Verbose`][13] @@ -832,4 +840,5 @@ Mode LastWriteTime Length Name [12]: xref:Microsoft.PowerShell.Utility.Write-Error [13]: xref:Microsoft.PowerShell.Utility.Write-Verbose [14]: xref:Microsoft.PowerShell.Utility.Write-Warning +[15]: about_Error_Handling.md diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md new file mode 100644 index 000000000000..18e4c7a32f88 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md @@ -0,0 +1,409 @@ +--- +description: Describes the types of errors in PowerShell and the mechanisms for handling them. +Locale: en-US +ms.date: 03/26/2026 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_error_handling?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Error_Handling +--- +# about_Error_Handling + +## Short description + +Describes the types of errors in PowerShell and the mechanisms for handling +them. + +## Long description + +PowerShell distinguishes three categories of errors: **non-terminating** +errors, **statement-terminating** errors, and **script-terminating** errors. +Understanding the distinction is essential for writing reliable scripts and +modules, because each category has different default behavior and requires +different handling techniques. + +Additionally, external (native) programs report failure through exit codes, +which PowerShell tracks separately from its own error system. + +## Types of errors + +### Non-terminating errors + +A non-terminating error reports a problem but does not stop the pipeline. The +command continues processing subsequent input objects. Non-terminating errors +are generated by: + +- The `Write-Error` cmdlet +- The `$PSCmdlet.WriteError()` method in advanced functions +- Cmdlets that encounter recoverable failures on individual input objects + +By default, PowerShell displays the error message and continues execution. + +```powershell +# Non-terminating error: the pipeline continues after the failure +'file1.txt', 'noSuchFile.txt', 'file3.txt' | ForEach-Object { + Get-Content $_ -ErrorAction Continue +} +``` + +In this example, `Get-Content` reports a non-terminating error for +`noSuchFile.txt` and then continues processing `file3.txt`. + +Non-terminating errors do **not** trigger `catch` or `trap` by default. + +### Statement-terminating errors + +A statement-terminating error stops the current statement (pipeline) from +running, but execution continues at the next statement in the script. +Statement-terminating errors are generated by: + +- The `$PSCmdlet.ThrowTerminatingError()` method in advanced functions and + compiled cmdlets +- Engine errors such as `CommandNotFoundException` (calling a command that does + not exist) and `ParameterBindingException` (invalid parameter arguments) +- Non-terminating errors **escalated** by `-ErrorAction Stop` or + `$ErrorActionPreference = 'Stop'` (see [How escalation works][05]) +- .NET method calls that throw exceptions, such as `[int]::Parse('abc')` + +```powershell +# Statement-terminating error: Get-Item fails, but the next statement runs +Get-Item -Path 'C:\NoSuchFile.txt' +Write-Output 'This still runs' +``` + +Statement-terminating errors can be caught by `try/catch` and `trap`. + +> [!NOTE] +> `.ThrowTerminatingError()` does not consult `-ErrorAction` or +> `$ErrorActionPreference` (except for the `Break` value, which enters the +> debugger). Once a cmdlet calls `.ThrowTerminatingError()`, the error is +> always thrown regardless of the caller's preferences. + +### Script-terminating errors + +A script-terminating error unwinds the entire call stack. Execution stops +completely unless the error is caught by a `try/catch` block or `trap` +statement. Script-terminating errors are generated by: + +- The `throw` keyword +- Certain critical engine failures + +```powershell +# 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)' +``` + +The `throw` keyword always generates a script-terminating error regardless of +`$ErrorActionPreference`. Setting `$ErrorActionPreference` to +`SilentlyContinue` or `Ignore` cannot suppress a `throw`. + +> [!IMPORTANT] +> The terms _statement-terminating_ and _script-terminating_ describe scope of +> impact, not severity. A statement-terminating error stops one statement. A +> script-terminating error stops the entire script and its callers. Both can be +> caught by `try/catch`. + +### External program errors + +External (native) programs do not participate in PowerShell's error system +directly. They report failure through a non-zero exit code, which PowerShell +stores in the `$LASTEXITCODE` automatic variable. + +```powershell +git clone https://example.com/nonexistent.git 2>$null +if ($LASTEXITCODE -ne 0) { + Write-Error "git failed with exit code $LASTEXITCODE" +} +``` + +By default, a non-zero exit code from a native program: + +- Sets `$?` to `$false` +- Does **not** generate an `ErrorRecord` in `$Error` +- Does **not** trigger `catch` or `trap` + +Starting in PowerShell 7.3, the +`$PSNativeCommandUseErrorActionPreference` +experimental preference variable, when set to `$true`, causes a non-zero exit +code to generate an error record that respects `$ErrorActionPreference`. + +## Error state variables + +PowerShell maintains several automatic variables that reflect the current error +state. + +### $? + +Contains `$true` if the last operation succeeded and `$false` if it produced +any error (non-terminating or terminating). For native commands, `$?` is set +based on the exit code: `$true` for exit code `0`, `$false` otherwise. + +```powershell +Get-Item -Path 'C:\NoSuchFile.txt' 2>$null +$? # False +``` + +### $Error + +An `ArrayList` that stores the most recent error records, with the most recent +error at index `0`. The list holds up to `$MaximumErrorCount` entries (default +256). + +All non-terminating and terminating errors are added to `$Error` unless +`-ErrorAction Ignore` is used, which prevents both display and recording. + +### $LASTEXITCODE + +Contains the exit code of the last native program that ran. A value of `0` +conventionally indicates success. Any non-zero value indicates failure. This +variable is not affected by PowerShell cmdlet errors. + +## Modifying error behavior + +### The -ErrorAction common parameter + +The `-ErrorAction` common parameter overrides `$ErrorActionPreference` for a +single command. It controls how PowerShell responds to **non-terminating** +errors from that command. + +| Value | Behavior | +|--------------------|---------------------------------------------------| +| `Continue` | Display the error and continue (default) | +| `SilentlyContinue` | Suppress display, add to `$Error`, continue | +| `Ignore` | Suppress display and do not add to `$Error` | +| `Stop` | **Escalate** to a statement-terminating error | +| `Inquire` | Prompt the user for a decision | +| `Break` | Enter the debugger | + +`-ErrorAction` does not change the behavior of errors generated by +`$PSCmdlet.ThrowTerminatingError()`. Those errors are always +statement-terminating regardless of the caller's preference. + +### The $ErrorActionPreference variable + +The `$ErrorActionPreference` preference variable applies to all commands in the +current scope and child scopes. It accepts the same values as `-ErrorAction` +except `Ignore` (which is valid only as a parameter value). + +```powershell +$ErrorActionPreference = 'Stop' +# All non-terminating errors in this scope now become statement-terminating +Write-Error 'This now throws' # Generates ActionPreferenceStopException +``` + +When `-ErrorAction` is specified on a command, it takes precedence over +`$ErrorActionPreference` for that command. + +### How escalation works + +When `-ErrorAction Stop` or `$ErrorActionPreference = 'Stop'` is in effect, +PowerShell converts non-terminating errors into statement-terminating errors +using the following mechanism: + +1. A cmdlet calls `WriteError()` internally to emit a non-terminating error. +1. The engine checks the effective `ErrorAction` preference for the command. +1. Because the preference is `Stop`, the engine creates an + `ActionPreferenceStopException` that wraps the original error record. +1. This exception propagates as a statement-terminating error. +1. If caught by `catch`, the original error information is accessible through + `$_.Exception.ErrorRecord`. + +```powershell +try { + # Without -ErrorAction Stop: non-terminating, catch does not fire + Write-Error 'This is non-terminating' + Write-Output 'Execution continues' +} catch { + Write-Output "Caught: $_" # Not reached +} + +try { + # With -ErrorAction Stop: escalated to statement-terminating + Write-Error 'This becomes terminating' -ErrorAction Stop +} catch { + Write-Output "Caught: $_" # Reached +} +``` + +Escalated errors can be caught by their original exception type. The engine +unwraps the `ActionPreferenceStopException` to find the underlying exception: + +```powershell +try { + Get-Item -Path 'C:\NoSuchFile.txt' -ErrorAction Stop +} catch [System.Management.Automation.ItemNotFoundException] { + Write-Output "File not found: $($_.Exception.Message)" +} +``` + +## Handling errors + +### try/catch/finally + +Use `try/catch/finally` to handle statement-terminating and script-terminating +errors. When an error occurs inside a `try` block, PowerShell searches for a +matching `catch` block. The `finally` block always runs, whether or not an +error occurred. + +```powershell +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 +} +``` + +Inside a `try` block, the engine sets an internal flag that causes non- +terminating errors escalated by `-ErrorAction Stop` or +`$ErrorActionPreference = 'Stop'` to propagate to the `catch` block. This +is designed behavior, not a special case. + +For full syntax details, see [about_Try_Catch_Finally][06]. + +### trap + +The `trap` statement handles terminating errors at the scope level. When an +error occurs anywhere in the enclosing scope, the `trap` block runs. + +- **Default** (no `break` or `continue`): The error is displayed and execution + continues at the next statement after the one that caused the error. +- **`continue`** in the trap: Suppresses the error message and resumes at the + next statement. +- **`break`** in the trap: The error propagates to the parent scope. + +```powershell +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' +``` + +For full syntax details, see [about_Trap][07]. + +## Reporting errors in functions and scripts + +When writing functions and scripts, choose the error-reporting mechanism that +matches the severity of the failure. + +### Non-terminating: Write-Error + +Use `Write-Error` when the function can continue processing other input. This +is appropriate for pipeline functions that process multiple objects and +encounter failures on individual items. + +```powershell +function Test-Path-Safe { + [CmdletBinding()] + param([Parameter(ValueFromPipeline)][string]$Path) + process { + if (-not (Test-Path $Path)) { + Write-Error "Path not found: $Path" + return + } + $Path + } +} +``` + +> [!NOTE] +> In advanced functions (those with `[CmdletBinding()]`), use +> `$PSCmdlet.WriteError()` instead of `Write-Error` to ensure that `$?` is +> properly set to `$false` in the caller's scope. The `Write-Error` cmdlet +> does not always set `$?` correctly. + +### Statement-terminating: $PSCmdlet.ThrowTerminatingError() + +Use `$PSCmdlet.ThrowTerminatingError()` when the function cannot continue at +all but the caller should decide how to handle the failure. This is the +recommended approach in advanced functions. + +```powershell +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 +} +``` + +After the error leaves the function, the caller treats it as a non-terminating +error by default. The caller can escalate it with `-ErrorAction Stop`. + +### Script-terminating: throw + +Use `throw` when recovery is not possible and the entire script should stop. + +```powershell +$config = Get-Content 'config.json' -ErrorAction SilentlyContinue | + ConvertFrom-Json + +if (-not $config) { + throw 'Cannot proceed without a valid configuration file.' +} +``` + +### Which mechanism to use + +| Situation | Mechanism | +|-----------|-----------| +| Processing multiple inputs; some may fail | `Write-Error` or `$PSCmdlet.WriteError()` | +| Function cannot continue; caller decides | `$PSCmdlet.ThrowTerminatingError()` | +| Entire script must stop immediately | `throw` | + +## Summary of error types + +| Property | Non-terminating | Statement-terminating | Script-terminating | +|----------|----------------|----------------------|-------------------| +| Generated by | `Write-Error`, `WriteError()` | `ThrowTerminatingError()`, engine errors, `-ErrorAction Stop` | `throw` | +| Scope of impact | Pipeline continues | Current statement stops; script continues | Call stack unwinds | +| Caught by `catch` | No (unless escalated) | Yes | Yes | +| Caught by `trap` | No (unless escalated) | Yes | Yes | +| Added to `$Error` | Yes (unless `Ignore`) | Yes | Yes | +| Sets `$?` to `$false` | Yes | Yes | Yes | +| Affected by `-ErrorAction` | Yes | No (already terminating) | No | + +## See also + +- [about_Automatic_Variables][01] +- [about_CommonParameters][02] +- [about_Preference_Variables][03] +- [about_Output_Streams][04] +- [about_Throw][08] +- [about_Trap][07] +- [about_Try_Catch_Finally][06] + + +[01]: about_Automatic_Variables.md +[02]: about_CommonParameters.md +[03]: about_Preference_Variables.md +[04]: about_Output_Streams.md +[05]: #how-escalation-works +[06]: about_Try_Catch_Finally.md +[07]: about_Trap.md +[08]: about_Throw.md diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md index d8f018167d39..c988626247d7 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md @@ -404,10 +404,13 @@ The valid values are as follows: preference. **Suspend** isn't a valid value for the `$ErrorActionPreference` variable. -`$ErrorActionPreference` and the **ErrorAction** parameter don't affect how -PowerShell responds to terminating errors that stop cmdlet processing. For more -information about the **ErrorAction** common parameter, see -[about_CommonParameters][29]. +`$ErrorActionPreference` and the **ErrorAction** parameter apply to +non-terminating errors. They don't change the behavior of +statement-terminating errors generated by `$PSCmdlet.ThrowTerminatingError()`. +However, when set to **Stop**, they escalate non-terminating errors to +statement-terminating errors. For more information about error categories, see +[about_Error_Handling][67]. For more information about the **ErrorAction** +common parameter, see [about_CommonParameters][29]. Many native commands write to `stderr` as an alternative stream for additional information. This behavior can cause confusion when looking through errors or @@ -1692,6 +1695,7 @@ At line:1 char:1 - [about_Automatic_Variables][28] - [about_CommonParameters][29] - [about_Environment_Variables][30] +- [about_Error_Handling][67] - [about_Profiles][36] - [about_Remote][39] - [about_Scopes][40] @@ -1763,3 +1767,4 @@ At line:1 char:1 [64]: xref:System.Text.UTF7Encoding [65]: xref:System.Text.UTF8Encoding [66]: about_Functions_CmdletBindingAttribute.md +[67]: about_Error_Handling.md diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md index b905c6af7f2d..ba9422d52170 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md @@ -1,5 +1,5 @@ --- -description: Describes the `throw` keyword, which generates a terminating error. +description: Describes the `throw` keyword, which generates a script-terminating error. Locale: en-US ms.date: 01/18/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_throw?view=powershell-7.6&WT.mc_id=ps-gethelp @@ -10,12 +10,18 @@ title: about_Throw ## Short description -Describes the `throw` keyword that generates a terminating error. +Describes the `throw` keyword that generates a script-terminating error. ## Long description -The `throw` keyword causes a terminating error. You can use the `throw` keyword -to stop the processing of a command, function, or script. +The `throw` keyword causes a script-terminating error. You can use the `throw` +keyword to stop the processing of a command, function, or script. + +Unlike statement-terminating errors (generated by +`$PSCmdlet.ThrowTerminatingError()`), the `throw` keyword unwinds the entire +call stack. Execution stops completely unless the error is caught by a +`try/catch` block or `trap` statement. For more information about error +categories, see [about_Error_Handling](about_Error_Handling.md). For example, you can use the `throw` keyword in the statement block of an `if` statement to respond to a condition or in the `catch` block of a @@ -123,6 +129,7 @@ for the correct way. - [about_Break](about_Break.md) - [about_Continue](about_Continue.md) +- [about_Error_Handling](about_Error_Handling.md) - [about_Scopes](about_Scopes.md) - [about_Trap](about_Trap.md) - [about_Try_Catch_Finally](about_Try_Catch_Finally.md) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Trap.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Trap.md index 1a59f55c7098..a6e0b7396b6e 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Trap.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Trap.md @@ -1,5 +1,5 @@ --- -description: Describes a keyword that handles a terminating error. +description: Describes a keyword that handles statement-terminating and script-terminating errors. Locale: en-US ms.date: 01/13/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_trap?view=powershell-7.6&WT.mc_id=ps-gethelp @@ -10,14 +10,16 @@ title: about_Trap ## Short description -Describes a keyword that handles a terminating error. +Describes a keyword that handles statement-terminating and script-terminating +errors. ## Long description -A terminating error stops a statement from running. If PowerShell doesn't -handle a terminating error in some way, PowerShell also stops running the -function or script in the current pipeline. In other languages, such as C#, -terminating errors are known as exceptions. +A terminating error stops a statement from running. PowerShell distinguishes +_statement-terminating_ errors (which stop only the current statement) from +_script-terminating_ errors (which unwind the entire call stack). The `trap` +keyword can handle both kinds. For more information about error categories, see +[about_Error_Handling][07]. The `trap` keyword specifies a list of statements to run when a terminating error occurs. `trap` statements can handle the terminating errors in the @@ -286,7 +288,7 @@ after loop In the output, you can see the loops continue until the last iteration. When the script tries to divide 1 by 0, PowerShell throws a terminating error. The -script skips the rest of the `foreach` statement, runs the `try` statement, +script skips the rest of the `foreach` statement, runs the `trap` statement, and continues after the `foreach` statement. ## Trapping errors and scope @@ -468,6 +470,7 @@ statement. For more information, see - [about_Break][01] - [about_Continue][02] +- [about_Error_Handling][07] - [about_Scopes][03] - [about_Throw][04] - [about_Try_Catch_Finally][05] @@ -479,3 +482,4 @@ statement. For more information, see [04]: about_Throw.md [05]: about_Try_Catch_Finally.md [06]: https://wikipedia.org/wiki/JavaScript_syntax#hoisting +[07]: about_Error_Handling.md diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md index 82b449f68137..56742b676ae6 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md @@ -1,5 +1,5 @@ --- -description: Describes how to use the `try`, `catch`, and `finally` blocks to handle terminating errors. +description: Describes how to use the `try`, `catch`, and `finally` blocks to handle statement-terminating and script-terminating errors. Locale: en-US ms.date: 01/13/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_try_catch_finally?view=powershell-7.6&WT.mc_id=ps-gethelp @@ -11,18 +11,24 @@ title: about_Try_Catch_Finally ## Short description Describes how to use the `try`, `catch`, and `finally` blocks to handle -terminating errors. +statement-terminating and script-terminating errors. ## Long description Use `try`, `catch`, and `finally` blocks to respond to or handle terminating -errors in scripts. The `trap` statement can also be used to handle terminating -errors in scripts. For more information, see [about_Trap][05]. - -A terminating error stops a statement from running. If PowerShell does not -handle a terminating error in some way, PowerShell also stops running the -function or script using the current pipeline. In other languages, such as C\#, -terminating errors are referred to as exceptions. +errors in scripts. PowerShell has two kinds of terminating errors: +_statement-terminating_ errors that stop the current statement and +_script-terminating_ errors that unwind the entire call stack. Both kinds are +caught by `try/catch`. The `trap` statement can also be used to handle +terminating errors. For more information, see [about_Trap][05]. For a +comprehensive overview of all error types, see [about_Error_Handling][06]. + +A statement-terminating error stops the current statement from running, but +PowerShell continues at the next statement unless the error is also +script-terminating. A script-terminating error (such as an error produced by +the `throw` keyword) stops the entire script unless caught by a `try/catch` +block or `trap` statement. In other languages, such as C\#, terminating errors +are referred to as exceptions. Use the `try` block to define a section of a script in which you want PowerShell to monitor for errors. When an error occurs within the `try` block, @@ -263,6 +269,7 @@ try { - [about_Break][01] - [about_Continue][02] +- [about_Error_Handling][06] - [about_Scopes][03] - [about_Throw][04] - [about_Trap][05] @@ -273,3 +280,4 @@ try { [03]: about_Scopes.md [04]: about_Throw.md [05]: about_Trap.md +[06]: about_Error_Handling.md diff --git a/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md b/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md index 17b065c9f7d1..e7c1ce90fa2b 100644 --- a/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md +++ b/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md @@ -44,12 +44,15 @@ it. ### Terminating and non-terminating errors -An exception is generally a terminating error. A thrown exception is either be caught or it -terminates the current execution. By default, a non-terminating error is generated by `Write-Error` -and it adds an error to the output stream without throwing an exception. - -I point this out because `Write-Error` and other non-terminating errors do not trigger the -`catch`. +PowerShell has three categories of errors. A _non-terminating error_ (generated +by `Write-Error`) adds an error to the error stream without stopping execution +and does not trigger `catch`. A _statement-terminating error_ (generated by +`$PSCmdlet.ThrowTerminatingError()` or by `-ErrorAction Stop` escalation) stops +the current statement but allows the script to continue at the next statement. +A _script-terminating error_ (generated by `throw`) unwinds the entire call +stack. Both statement-terminating and script-terminating errors can be caught by +`try/catch`. For a comprehensive reference, see +[about_Error_Handling](/powershell/module/microsoft.powershell.core/about/about_error_handling). ### Swallowing an exception @@ -556,22 +559,28 @@ catch This changes the source of the error to the Cmdlet and hide the internals of your function from the users of your Cmdlet. -## Try can create terminating errors +## How try/catch changes error propagation -Kirk Munro points out that some exceptions are only terminating errors when executed inside a -`try/catch` block. Here is the example he gave me that generates a divide by zero runtime exception. +Inside a `try` block, PowerShell sets an internal flag that causes all +statement-terminating errors to propagate to the `catch` block. This is by +design, not a corner case. The following example demonstrates this behavior. + +Outside `try/catch`, a statement-terminating error from a child scope does not +stop the parent scope. Here is a function that generates a divide by zero +runtime exception. ```powershell function Start-Something { 1/(1-1) } ``` -Then invoke it like this to see it generate the error and still output the message. +Invoke it like this to see the error reported while the script continues. ```powershell &{ Start-Something; Write-Output "We did it. Send Email" } ``` -But by placing that same code inside a `try/catch`, we see something else happen. +But placing that same code inside a `try/catch`, the error propagates to the +`catch` block. ```powershell try @@ -584,18 +593,18 @@ catch } ``` -We see the error become a terminating error and not output the first message. What I don't like -about this one is that you can have this code in a function and it acts differently if someone is -using a `try/catch`. - -I have not ran into issues with this myself but it is corner case to be aware of. +The error is caught and the subsequent `Write-Output` inside the script block +does not run. This is standard `try/catch` behavior — all terminating errors +within the `try` block are caught, whether they originate in the current scope +or in a child scope. ### $PSCmdlet.ThrowTerminatingError() inside try/catch -One nuance of `$PSCmdlet.ThrowTerminatingError()` is that it creates a terminating error within your -Cmdlet but it turns into a non-terminating error after it leaves your Cmdlet. This leaves the burden -on the caller of your function to decide how to handle the error. They can turn it back into a -terminating error by using `-ErrorAction Stop` or calling it from within a `try{...}catch{...}`. +`$PSCmdlet.ThrowTerminatingError()` creates a statement-terminating error +within the cmdlet. After the error leaves the cmdlet, the caller treats it as a +non-terminating error by default. The caller can escalate it back to a +terminating error by using `-ErrorAction Stop` or calling it from within a +`try{...}catch{...}`. ### Public function templates From c66211988b6ecb1c26b47bf514c0bf502c8f134e Mon Sep 17 00:00:00 2001 From: SufficientDaikon Date: Sat, 28 Mar 2026 10:43:42 +0200 Subject: [PATCH 02/10] Address mklement0 review: fix error terminology precision - -ErrorAction Stop promotes to script-terminating, not statement-terminating - $ErrorActionPreference applies to both non-terminating and statement-terminating errors (unlike -ErrorAction parameter) - $ErrorActionPreference = 'Ignore' is now accepted (remove outdated caveat) - Native command non-zero exit emits non-terminating NativeCommandExitException Co-Authored-By: Claude Opus 4.6 --- .../About/about_CommonParameters.md | 4 ++-- .../About/about_Error_Handling.md | 12 +++++++----- .../About/about_Preference_Variables.md | 11 ++++++----- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md index e433623c9fe8..2b648feab1d8 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md @@ -128,8 +128,8 @@ and execution continues unless you use the `ErrorAction` parameter. The `-ErrorAction` parameter doesn't prevent statement-terminating errors (such as missing data, parameters that aren't valid, or insufficient permissions) from stopping the current statement. However, when set to `Stop`, -it escalates non-terminating errors to statement-terminating errors, making -them catchable by `try/catch`. For more information about error categories, see +it escalates non-terminating errors to script-terminating errors, making them +catchable by `try/catch`. For more information about error categories, see [about_Error_Handling][15]. - `Break` Enters the debugger when an error occurs or an exception is raised. diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md index 18e4c7a32f88..55f67f3f9f26 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md @@ -130,7 +130,10 @@ By default, a non-zero exit code from a native program: Starting in PowerShell 7.3, the `$PSNativeCommandUseErrorActionPreference` experimental preference variable, when set to `$true`, causes a non-zero exit -code to generate an error record that respects `$ErrorActionPreference`. +code to emit a **non-terminating error** whose message states the specific exit +code (a `NativeCommandExitException`). This error then respects +`$ErrorActionPreference`, so setting it to `Stop` promotes the error to a +script-terminating error that can be caught with `try`/`catch`. ## Error state variables @@ -176,7 +179,7 @@ errors from that command. | `Continue` | Display the error and continue (default) | | `SilentlyContinue` | Suppress display, add to `$Error`, continue | | `Ignore` | Suppress display and do not add to `$Error` | -| `Stop` | **Escalate** to a statement-terminating error | +| `Stop` | **Escalate** to a script-terminating error | | `Inquire` | Prompt the user for a decision | | `Break` | Enter the debugger | @@ -187,12 +190,11 @@ statement-terminating regardless of the caller's preference. ### The $ErrorActionPreference variable The `$ErrorActionPreference` preference variable applies to all commands in the -current scope and child scopes. It accepts the same values as `-ErrorAction` -except `Ignore` (which is valid only as a parameter value). +current scope and child scopes. It accepts the same values as `-ErrorAction`. ```powershell $ErrorActionPreference = 'Stop' -# All non-terminating errors in this scope now become statement-terminating +# All non-terminating errors in this scope now become script-terminating Write-Error 'This now throws' # Generates ActionPreferenceStopException ``` diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md index c988626247d7..1ae5d5e4af57 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md @@ -404,11 +404,12 @@ The valid values are as follows: preference. **Suspend** isn't a valid value for the `$ErrorActionPreference` variable. -`$ErrorActionPreference` and the **ErrorAction** parameter apply to -non-terminating errors. They don't change the behavior of -statement-terminating errors generated by `$PSCmdlet.ThrowTerminatingError()`. -However, when set to **Stop**, they escalate non-terminating errors to -statement-terminating errors. For more information about error categories, see +`$ErrorActionPreference` applies to **both** non-terminating and +statement-terminating errors. Unlike the `-ErrorAction` parameter (which only +affects non-terminating errors), the preference variable can also suppress or +escalate errors generated by `$PSCmdlet.ThrowTerminatingError()`. +When set to **Stop**, it escalates non-terminating errors to +script-terminating errors. For more information about error categories, see [about_Error_Handling][67]. For more information about the **ErrorAction** common parameter, see [about_CommonParameters][29]. From 4f51cce3222a394757b9c62daf0299d4c0849597 Mon Sep 17 00:00:00 2001 From: SufficientDaikon Date: Sat, 28 Mar 2026 16:18:55 +0200 Subject: [PATCH 03/10] Comprehensive accuracy overhaul: escalation semantics, asymmetry, parse errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Major corrections verified against PowerShell engine source code: - Fix: -ErrorAction Stop produces script-terminating errors, not statement-terminating. ActionPreferenceStopException sets SuppressPromptInInterpreter=true, causing call-stack unwinding. Fixed across all 4 affected files. - Add: New "$ErrorActionPreference asymmetry" section in about_Error_Handling documenting that $ErrorActionPreference applies to BOTH non-terminating and statement-terminating errors, while -ErrorAction only affects non-terminating errors. Includes runnable demo and IMPORTANT callout for exceptions (SuppressPromptInInterpreter, PS classes, PipelineStoppedException). - Add: Parse errors to script-terminating generators list (per mklement0 review comment). - Fix: about_Preference_Variables Ignore bullet incorrectly stated "Ignore isn't a valid value for $ErrorActionPreference" — it is accepted (only Suspend is rejected per ExecutionContext.cs). - Fix: NOTE block on ThrowTerminatingError now correctly explains that $ErrorActionPreference can suppress it via the engine's statement-level handler in MiscOps.CheckActionPreference. - Fix: Summary table updated — -ErrorAction Stop moved from statement-terminating to script-terminating column, new row added for $ErrorActionPreference behavior per error type. - Fix: everything-about-exceptions.md — three remaining instances of vague "terminating error" updated to "script-terminating error" for throw and -ErrorAction Stop contexts. All claims verified with live PowerShell 7.x tests: 1. -ErrorAction Stop: next statement in scriptblock does NOT run (script-terminating) 2. Parse errors: caught as MethodInvocationException 3. $ErrorActionPreference='Ignore': accepted without error 4. $ErrorActionPreference='SilentlyContinue': suppresses ThrowTerminatingError 5. -ErrorAction SilentlyContinue: does NOT suppress ThrowTerminatingError Co-Authored-By: Claude Opus 4.6 --- .../About/about_CommonParameters.md | 2 +- .../About/about_Error_Handling.md | 75 ++++++++++++++++--- .../About/about_Preference_Variables.md | 7 +- .../deep-dives/everything-about-exceptions.md | 15 ++-- 4 files changed, 77 insertions(+), 22 deletions(-) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md index 2b648feab1d8..48d5b03b21fa 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md @@ -144,7 +144,7 @@ catchable by `try/catch`. For more information about error categories, see - `SilentlyContinue` suppresses the error message and continues executing the command. - `Stop` displays the error message and stops executing the command. The - `Stop` value escalates the non-terminating error to a statement-terminating + `Stop` value escalates the non-terminating error to a script-terminating error by generating an `ActionPreferenceStopException`. The error can then be caught by a `try/catch` block or `trap` statement. - `Suspend` is only available for workflows which aren't supported in diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md index 55f67f3f9f26..4719a9196ac4 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md @@ -60,8 +60,6 @@ Statement-terminating errors are generated by: compiled cmdlets - Engine errors such as `CommandNotFoundException` (calling a command that does not exist) and `ParameterBindingException` (invalid parameter arguments) -- Non-terminating errors **escalated** by `-ErrorAction Stop` or - `$ErrorActionPreference = 'Stop'` (see [How escalation works][05]) - .NET method calls that throw exceptions, such as `[int]::Parse('abc')` ```powershell @@ -73,10 +71,14 @@ Write-Output 'This still runs' Statement-terminating errors can be caught by `try/catch` and `trap`. > [!NOTE] -> `.ThrowTerminatingError()` does not consult `-ErrorAction` or -> `$ErrorActionPreference` (except for the `Break` value, which enters the -> debugger). Once a cmdlet calls `.ThrowTerminatingError()`, the error is -> always thrown regardless of the caller's preferences. +> `.ThrowTerminatingError()` does not consult the `-ErrorAction` parameter +> (except for the `Break` value, which enters the debugger). However, +> `$ErrorActionPreference` _does_ apply to statement-terminating errors +> through the engine's statement-level handler. For example, +> `$ErrorActionPreference = 'SilentlyContinue'` can suppress a +> statement-terminating error so that the script continues at the next +> statement. The `-ErrorAction` parameter cannot do this. For details, see +> [The $ErrorActionPreference asymmetry][09]. ### Script-terminating errors @@ -85,6 +87,9 @@ completely unless the error is caught by a `try/catch` block or `trap` statement. Script-terminating errors are generated by: - The `throw` keyword +- Parse errors (syntax errors that prevent the script from being compiled) +- Non-terminating errors **escalated** by `-ErrorAction Stop` or + `$ErrorActionPreference = 'Stop'` (see [How escalation works][05]) - Certain critical engine failures ```powershell @@ -204,14 +209,15 @@ When `-ErrorAction` is specified on a command, it takes precedence over ### How escalation works When `-ErrorAction Stop` or `$ErrorActionPreference = 'Stop'` is in effect, -PowerShell converts non-terminating errors into statement-terminating errors +PowerShell converts non-terminating errors into script-terminating errors using the following mechanism: 1. A cmdlet calls `WriteError()` internally to emit a non-terminating error. 1. The engine checks the effective `ErrorAction` preference for the command. 1. Because the preference is `Stop`, the engine creates an `ActionPreferenceStopException` that wraps the original error record. -1. This exception propagates as a statement-terminating error. +1. This exception has `SuppressPromptInInterpreter` set to `true`, which + causes it to propagate up the call stack like a script-terminating error. 1. If caught by `catch`, the original error information is accessible through `$_.Exception.ErrorRecord`. @@ -225,7 +231,7 @@ try { } try { - # With -ErrorAction Stop: escalated to statement-terminating + # With -ErrorAction Stop: escalated to script-terminating Write-Error 'This becomes terminating' -ErrorAction Stop } catch { Write-Output "Caught: $_" # Reached @@ -243,6 +249,51 @@ try { } ``` +### The $ErrorActionPreference asymmetry + +The `-ErrorAction` parameter and the `$ErrorActionPreference` variable behave +differently with terminating errors. This is an important asymmetry: + +- **`-ErrorAction`** only affects **non-terminating** errors. When a cmdlet + calls `$PSCmdlet.ThrowTerminatingError()`, the `-ErrorAction` parameter is + ignored (except for `Break`, which enters the debugger). The error is always + thrown. + +- **`$ErrorActionPreference`** affects **both** non-terminating and + statement-terminating errors. The engine's statement-level error handler + reads `$ErrorActionPreference` (not the `-ErrorAction` parameter) and can + suppress a statement-terminating error when the value is `SilentlyContinue` + or `Ignore`. + +```powershell +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' +``` + +> [!IMPORTANT] +> `$ErrorActionPreference` cannot suppress errors that have +> `SuppressPromptInInterpreter` set to `true` (such as +> `ActionPreferenceStopException` from `-ErrorAction Stop` escalation), +> errors inside PowerShell class methods, or `PipelineStoppedException`. +> These always propagate regardless of the preference variable. + ## Handling errors ### try/catch/finally @@ -382,13 +433,14 @@ if (-not $config) { | Property | Non-terminating | Statement-terminating | Script-terminating | |----------|----------------|----------------------|-------------------| -| Generated by | `Write-Error`, `WriteError()` | `ThrowTerminatingError()`, engine errors, `-ErrorAction Stop` | `throw` | +| Generated by | `Write-Error`, `WriteError()` | `ThrowTerminatingError()`, engine errors, .NET method exceptions | `throw`, parse errors, `-ErrorAction Stop` escalation | | Scope of impact | Pipeline continues | Current statement stops; script continues | Call stack unwinds | | Caught by `catch` | No (unless escalated) | Yes | Yes | | Caught by `trap` | No (unless escalated) | Yes | Yes | | Added to `$Error` | Yes (unless `Ignore`) | Yes | Yes | | Sets `$?` to `$false` | Yes | Yes | Yes | -| Affected by `-ErrorAction` | Yes | No (already terminating) | No | +| Affected by `-ErrorAction` | Yes | No (`Break` only) | No | +| Affected by `$ErrorActionPreference` | Yes | Yes (can suppress) | `throw`: No; escalated: No | ## See also @@ -409,3 +461,4 @@ if (-not $config) { [06]: about_Try_Catch_Finally.md [07]: about_Trap.md [08]: about_Throw.md +[09]: #the-erroractionpreference-asymmetry diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md index 1ae5d5e4af57..f5f4406f4665 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md @@ -388,9 +388,10 @@ The valid values are as follows: raised. - **Continue**: (Default) Displays the error message and continues executing. - **Ignore**: Suppresses the error message and continues to execute the - command. The **Ignore** value is intended for per-command use, not for use as - saved preference. **Ignore** isn't a valid value for the - `$ErrorActionPreference` variable. + command. Unlike **SilentlyContinue**, **Ignore** doesn't add the error + message to the `$Error` automatic variable. The **Ignore** value is also + valid for `$ErrorActionPreference`, where it suppresses both non-terminating + and statement-terminating errors without recording them in `$Error`. - **Inquire**: Displays the error message and asks you whether you want to continue. - **SilentlyContinue**: No effect. The error message isn't displayed and diff --git a/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md b/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md index e7c1ce90fa2b..1b730fa65e6d 100644 --- a/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md +++ b/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md @@ -47,10 +47,11 @@ it. PowerShell has three categories of errors. A _non-terminating error_ (generated by `Write-Error`) adds an error to the error stream without stopping execution and does not trigger `catch`. A _statement-terminating error_ (generated by -`$PSCmdlet.ThrowTerminatingError()` or by `-ErrorAction Stop` escalation) stops -the current statement but allows the script to continue at the next statement. -A _script-terminating error_ (generated by `throw`) unwinds the entire call -stack. Both statement-terminating and script-terminating errors can be caught by +`$PSCmdlet.ThrowTerminatingError()`, engine errors, or .NET method exceptions) +stops the current statement but allows the script to continue at the next +statement. A _script-terminating error_ (generated by `throw`, parse errors, or +`-ErrorAction Stop` escalation) unwinds the entire call stack. Both +statement-terminating and script-terminating errors can be caught by `try/catch`. For a comprehensive reference, see [about_Error_Handling](/powershell/module/microsoft.powershell.core/about/about_error_handling). @@ -74,7 +75,7 @@ function Start-Something } ``` -This creates a runtime exception that is a terminating error. It's handled by a `catch` in a +This creates a runtime exception that is a script-terminating error. It's handled by a `catch` in a calling function or exits the script with a message like this. ```powershell @@ -91,7 +92,7 @@ At line:1 char:1 #### Write-Error -ErrorAction Stop I mentioned that `Write-Error` doesn't throw a terminating error by default. If you specify -`-ErrorAction Stop`, `Write-Error` generates a terminating error that can be handled with a +`-ErrorAction Stop`, `Write-Error` generates a script-terminating error that can be handled with a `catch`. ```powershell @@ -103,7 +104,7 @@ Thank you to Lee Dailey for reminding about using `-ErrorAction Stop` this way. #### Cmdlet -ErrorAction Stop If you specify `-ErrorAction Stop` on any advanced function or cmdlet, it turns all `Write-Error` -statements into terminating errors that stop execution or that can be handled by a `catch`. +statements into script-terminating errors that stop execution or that can be handled by a `catch`. ```powershell Start-Something -ErrorAction Stop From f25403cc376ce108da5f6e4f20f369c017c474aa Mon Sep 17 00:00:00 2001 From: SufficientDaikon Date: Sat, 28 Mar 2026 17:22:35 +0200 Subject: [PATCH 04/10] Address mklement0 feedback: throw suppression, Ignore/$Error, advanced escalation Three corrections based on mklement0's review: 1. throw CAN be suppressed by $ErrorActionPreference when set to SilentlyContinue or Ignore. Removed the incorrect claim that throw is "always" script-terminating "regardless of $ErrorActionPreference". Also documented that -ErrorAction on advanced functions translates to a scope-local $ErrorActionPreference, so it suppresses throw too. 2. Added NOTE that $ErrorActionPreference = 'Ignore' still records terminating errors in $Error. Ignore only prevents $Error recording for non-terminating errors. 3. Escalation section now documents the advanced vs. non-advanced distinction: $ErrorActionPreference = 'Stop' produces script-terminating errors in non-advanced contexts, but statement-terminating errors in advanced contexts ([CmdletBinding()]). Summary table updated to reflect both contexts. Co-Authored-By: Claude Opus 4.6 --- .../About/about_Error_Handling.md | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md index 4719a9196ac4..54e0739aa912 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md @@ -89,7 +89,8 @@ statement. Script-terminating errors are generated by: - The `throw` keyword - Parse errors (syntax errors that prevent the script from being compiled) - Non-terminating errors **escalated** by `-ErrorAction Stop` or - `$ErrorActionPreference = 'Stop'` (see [How escalation works][05]) + `$ErrorActionPreference = 'Stop'` in non-advanced contexts (see + [How escalation works][05]) - Certain critical engine failures ```powershell @@ -103,9 +104,17 @@ Test-Throw Write-Output 'This never runs either (unless caught)' ``` -The `throw` keyword always generates a script-terminating error regardless of -`$ErrorActionPreference`. Setting `$ErrorActionPreference` to -`SilentlyContinue` or `Ignore` cannot suppress a `throw`. +The `throw` keyword generates a script-terminating error by default. +However, `$ErrorActionPreference` _can_ suppress `throw` when set to +`SilentlyContinue` or `Ignore`. When calling an advanced function with +`-ErrorAction SilentlyContinue`, the parameter translates to a scope-local +`$ErrorActionPreference` value, so it also suppresses `throw` inside that +function. + +> [!NOTE] +> Even with `$ErrorActionPreference = 'Ignore'`, a `throw` that is suppressed +> still records an entry in `$Error`. The `Ignore` value only prevents +> `$Error` recording for **non-terminating** errors. > [!IMPORTANT] > The terms _statement-terminating_ and _script-terminating_ describe scope of @@ -209,18 +218,38 @@ When `-ErrorAction` is specified on a command, it takes precedence over ### How escalation works When `-ErrorAction Stop` or `$ErrorActionPreference = 'Stop'` is in effect, -PowerShell converts non-terminating errors into script-terminating errors -using the following mechanism: +PowerShell converts non-terminating errors into terminating errors using the +following mechanism: 1. A cmdlet calls `WriteError()` internally to emit a non-terminating error. 1. The engine checks the effective `ErrorAction` preference for the command. 1. Because the preference is `Stop`, the engine creates an `ActionPreferenceStopException` that wraps the original error record. -1. This exception has `SuppressPromptInInterpreter` set to `true`, which - causes it to propagate up the call stack like a script-terminating error. 1. If caught by `catch`, the original error information is accessible through `$_.Exception.ErrorRecord`. +The scope of the escalated error depends on context: + +- In **non-advanced** scripts, functions, or script blocks, + `$ErrorActionPreference = 'Stop'` escalates to a **script-terminating** + error. The error propagates up the call stack. +- In **advanced** functions and script blocks (those with `[CmdletBinding()]`), + the error remains **statement-terminating**. Execution continues at the + next statement after the call. +- Passing `-ErrorAction Stop` to an advanced function has the same effect as + setting `$ErrorActionPreference = 'Stop'` inside it, because `-ErrorAction` + translates to a scope-local `$ErrorActionPreference` value. + +```powershell +# NON-advanced: script-terminating ('after' does NOT print) +& { param() $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' } 2>$null +'after' + +# ADVANCED: statement-terminating ('after' DOES print) +& { [CmdletBinding()]param() $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' } 2>$null +'after' +``` + ```powershell try { # Without -ErrorAction Stop: non-terminating, catch does not fire @@ -433,14 +462,14 @@ if (-not $config) { | Property | Non-terminating | Statement-terminating | Script-terminating | |----------|----------------|----------------------|-------------------| -| Generated by | `Write-Error`, `WriteError()` | `ThrowTerminatingError()`, engine errors, .NET method exceptions | `throw`, parse errors, `-ErrorAction Stop` escalation | +| Generated by | `Write-Error`, `WriteError()` | `ThrowTerminatingError()`, engine errors, .NET method exceptions, `-ErrorAction Stop` in advanced contexts | `throw`, parse errors, `-ErrorAction Stop` in non-advanced contexts | | Scope of impact | Pipeline continues | Current statement stops; script continues | Call stack unwinds | | Caught by `catch` | No (unless escalated) | Yes | Yes | | Caught by `trap` | No (unless escalated) | Yes | Yes | | Added to `$Error` | Yes (unless `Ignore`) | Yes | Yes | | Sets `$?` to `$false` | Yes | Yes | Yes | | Affected by `-ErrorAction` | Yes | No (`Break` only) | No | -| Affected by `$ErrorActionPreference` | Yes | Yes (can suppress) | `throw`: No; escalated: No | +| Affected by `$ErrorActionPreference` | Yes | Yes (can suppress) | `throw`: Yes (can suppress); escalated: depends on context | ## See also From d91c08d110c262efc4bd47f46538d69fbaab468e Mon Sep 17 00:00:00 2001 From: SufficientDaikon Date: Sat, 28 Mar 2026 17:33:19 +0200 Subject: [PATCH 05/10] Refine escalation terminology: terminating (context-dependent) not script-terminating Per mklement0 feedback, -ErrorAction Stop escalation scope depends on whether the context is advanced ([CmdletBinding()]) or non-advanced. Changed about_CommonParameters.md and ErrorAction table to say "terminating error" generically, with escalation section providing the full advanced vs. non-advanced explanation. Co-Authored-By: Claude Opus 4.6 --- .../About/about_CommonParameters.md | 4 ++-- .../About/about_Error_Handling.md | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md index 48d5b03b21fa..25056ec574ef 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md @@ -144,8 +144,8 @@ catchable by `try/catch`. For more information about error categories, see - `SilentlyContinue` suppresses the error message and continues executing the command. - `Stop` displays the error message and stops executing the command. The - `Stop` value escalates the non-terminating error to a script-terminating - error by generating an `ActionPreferenceStopException`. The error can then + `Stop` value escalates the non-terminating error to a terminating error + by generating an `ActionPreferenceStopException`. The error can then be caught by a `try/catch` block or `trap` statement. - `Suspend` is only available for workflows which aren't supported in PowerShell 6 and beyond. diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md index 54e0739aa912..6008ab4b04ad 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md @@ -172,7 +172,9 @@ error at index `0`. The list holds up to `$MaximumErrorCount` entries (default 256). All non-terminating and terminating errors are added to `$Error` unless -`-ErrorAction Ignore` is used, which prevents both display and recording. +`-ErrorAction Ignore` is used on non-terminating errors, which prevents both +display and recording. For terminating errors, `Ignore` suppresses display but +still records the error in `$Error`. ### $LASTEXITCODE @@ -193,7 +195,7 @@ errors from that command. | `Continue` | Display the error and continue (default) | | `SilentlyContinue` | Suppress display, add to `$Error`, continue | | `Ignore` | Suppress display and do not add to `$Error` | -| `Stop` | **Escalate** to a script-terminating error | +| `Stop` | **Escalate** to a terminating error (see [How escalation works][05]) | | `Inquire` | Prompt the user for a decision | | `Break` | Enter the debugger | @@ -208,7 +210,7 @@ current scope and child scopes. It accepts the same values as `-ErrorAction`. ```powershell $ErrorActionPreference = 'Stop' -# All non-terminating errors in this scope now become script-terminating +# All non-terminating errors in this scope now become terminating Write-Error 'This now throws' # Generates ActionPreferenceStopException ``` @@ -260,7 +262,7 @@ try { } try { - # With -ErrorAction Stop: escalated to script-terminating + # With -ErrorAction Stop: escalated to terminating Write-Error 'This becomes terminating' -ErrorAction Stop } catch { Write-Output "Caught: $_" # Reached From bd9a4314dc0cf3d232e80ef5b0702ffad10c3c95 Mon Sep 17 00:00:00 2001 From: SufficientDaikon Date: Sun, 29 Mar 2026 00:29:32 +0200 Subject: [PATCH 06/10] Extend error handling accuracy to about_Throw, about_Try_Catch_Finally - about_Throw: Add $ErrorActionPreference suppression caveat (throw CAN be suppressed by SilentlyContinue/Ignore), add NOTE block with Ignore still recording in $Error, update description to "by default" - about_Try_Catch_Finally: Add NOTE about throw suppression with cross-ref to about_Error_Handling, fix $tempPath -> $tempFile code bug (line 264) - about_Preference_Variables: Fix Ignore bullet - clarify that Ignore only prevents $Error recording for non-terminating errors, not terminating - everything-about-exceptions: Change -ErrorAction Stop from "script-terminating" to "terminating" (context-dependent behavior) All claims verified against live PowerShell 7.6 behavior. Co-Authored-By: Claude Opus 4.6 --- .../About/about_Preference_Variables.md | 4 ++- .../About/about_Throw.md | 27 ++++++++++++++----- .../About/about_Try_Catch_Finally.md | 14 +++++++--- .../deep-dives/everything-about-exceptions.md | 4 +-- 4 files changed, 35 insertions(+), 14 deletions(-) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md index f5f4406f4665..cdd9e6150c7e 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md @@ -391,7 +391,9 @@ The valid values are as follows: command. Unlike **SilentlyContinue**, **Ignore** doesn't add the error message to the `$Error` automatic variable. The **Ignore** value is also valid for `$ErrorActionPreference`, where it suppresses both non-terminating - and statement-terminating errors without recording them in `$Error`. + and statement-terminating errors. However, **Ignore** only prevents `$Error` + recording for non-terminating errors. Terminating errors that are suppressed + by `Ignore` are still recorded in `$Error`. - **Inquire**: Displays the error message and asks you whether you want to continue. - **SilentlyContinue**: No effect. The error message isn't displayed and diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md index ba9422d52170..292aa1983243 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md @@ -1,7 +1,7 @@ --- -description: Describes the `throw` keyword, which generates a script-terminating error. +description: Describes the `throw` keyword, which generates a script-terminating error by default. Locale: en-US -ms.date: 01/18/2026 +ms.date: 03/29/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_throw?view=powershell-7.6&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Throw @@ -10,18 +10,31 @@ title: about_Throw ## Short description -Describes the `throw` keyword that generates a script-terminating error. +Describes the `throw` keyword that generates a script-terminating error by +default. ## Long description -The `throw` keyword causes a script-terminating error. You can use the `throw` -keyword to stop the processing of a command, function, or script. +The `throw` keyword causes a script-terminating error by default. You can use +the `throw` keyword to stop the processing of a command, function, or script. Unlike statement-terminating errors (generated by `$PSCmdlet.ThrowTerminatingError()`), the `throw` keyword unwinds the entire call stack. Execution stops completely unless the error is caught by a -`try/catch` block or `trap` statement. For more information about error -categories, see [about_Error_Handling](about_Error_Handling.md). +`try/catch` block or `trap` statement. + +> [!NOTE] +> `$ErrorActionPreference` can suppress `throw`. When set to +> `SilentlyContinue` or `Ignore`, the error does not propagate and +> execution continues at the next statement. When calling an advanced +> function with `-ErrorAction SilentlyContinue`, the parameter translates +> to a scope-local `$ErrorActionPreference` value, so it also suppresses +> `throw` inside that function. Even when suppressed, `throw` still records +> an entry in `$Error` — `Ignore` only prevents `$Error` recording for +> non-terminating errors. + +For more information about error categories and `$ErrorActionPreference` +behavior, see [about_Error_Handling](about_Error_Handling.md). For example, you can use the `throw` keyword in the statement block of an `if` statement to respond to a condition or in the `catch` block of a diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md index 56742b676ae6..4aef7ac61125 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md @@ -1,7 +1,7 @@ --- description: Describes how to use the `try`, `catch`, and `finally` blocks to handle statement-terminating and script-terminating errors. Locale: en-US -ms.date: 01/13/2026 +ms.date: 03/29/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_try_catch_finally?view=powershell-7.6&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Try_Catch_Finally @@ -27,8 +27,13 @@ A statement-terminating error stops the current statement from running, but PowerShell continues at the next statement unless the error is also script-terminating. A script-terminating error (such as an error produced by the `throw` keyword) stops the entire script unless caught by a `try/catch` -block or `trap` statement. In other languages, such as C\#, terminating errors -are referred to as exceptions. +block or `trap` statement. + +> [!NOTE] +> `$ErrorActionPreference` can suppress `throw`. When set to +> `SilentlyContinue` or `Ignore`, the error does not propagate and +> execution continues at the next statement. For details, see the +> [_throw_ suppression section][07] in **about_Error_Handling**. Use the `try` block to define a section of a script in which you want PowerShell to monitor for errors. When an error occurs within the `try` block, @@ -261,7 +266,7 @@ try { "An error occurred that could not be resolved." } finally { $wc.Dispose() - if (Test-Path $tempPath) { Remove-Item $tempFile } + if (Test-Path $tempFile) { Remove-Item $tempFile } } ``` @@ -281,3 +286,4 @@ try { [04]: about_Throw.md [05]: about_Trap.md [06]: about_Error_Handling.md +[07]: about_Error_Handling.md#script-terminating-errors diff --git a/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md b/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md index 1b730fa65e6d..2e1d6408c7de 100644 --- a/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md +++ b/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md @@ -92,7 +92,7 @@ At line:1 char:1 #### Write-Error -ErrorAction Stop I mentioned that `Write-Error` doesn't throw a terminating error by default. If you specify -`-ErrorAction Stop`, `Write-Error` generates a script-terminating error that can be handled with a +`-ErrorAction Stop`, `Write-Error` generates a terminating error that can be handled with a `catch`. ```powershell @@ -104,7 +104,7 @@ Thank you to Lee Dailey for reminding about using `-ErrorAction Stop` this way. #### Cmdlet -ErrorAction Stop If you specify `-ErrorAction Stop` on any advanced function or cmdlet, it turns all `Write-Error` -statements into script-terminating errors that stop execution or that can be handled by a `catch`. +statements into terminating errors that stop execution or that can be handled by a `catch`. ```powershell Start-Something -ErrorAction Stop From 7c16ba2d96fc19b1e0d9b52caa2010bf2a5b0aff Mon Sep 17 00:00:00 2001 From: SufficientDaikon Date: Sun, 29 Mar 2026 00:43:22 +0200 Subject: [PATCH 07/10] Final polish: qualify Ignore/$Error claims and About.md index - About.md: Update throw index to "script-terminating error by default" - about_Automatic_Variables: Qualify $Error/Ignore as non-terminating only - about_CommonParameters: Qualify Ignore bullet as non-terminating only Co-Authored-By: Claude Opus 4.6 --- reference/7.6/Microsoft.PowerShell.Core/About/About.md | 3 ++- .../About/about_Automatic_Variables.md | 4 ++-- .../About/about_CommonParameters.md | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/About.md b/reference/7.6/Microsoft.PowerShell.Core/About/About.md index dc02c67bc981..196121ec30fc 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/About.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/About.md @@ -589,7 +589,8 @@ the current session process. ### [about_Throw](about_Throw.md) -Describes the `throw` keyword that generates a terminating error. +Describes the `throw` keyword that generates a script-terminating error by +default. ### [about_Trap](about_Trap.md) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md index 6abf3a21a87b..0ebc43571798 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md @@ -167,8 +167,8 @@ Contains a list of names of the experimental features that are enabled. Contains an array of error objects that represent the most recent errors. The most recent error is the first error object in the array `$Error[0]`. -To prevent an error from being added to the `$Error` array, use the -**ErrorAction** common parameter with a value of **Ignore**. For more +To prevent a non-terminating error from being added to the `$Error` array, use +the **ErrorAction** common parameter with a value of **Ignore**. For more information, see [about_CommonParameters][53]. ### `$Event` diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md index 25056ec574ef..f381103d5fe0 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md @@ -136,9 +136,9 @@ catchable by `try/catch`. For more information about error categories, see - `Continue` displays the error message and continues executing the command. `Continue` is the default. - `Ignore` suppresses the error message and continues executing the command. - Unlike `SilentlyContinue`, `Ignore` doesn't add the error message to the - `$Error` automatic variable. The `Ignore` value is introduced in PowerShell - 3.0. + Unlike `SilentlyContinue`, `Ignore` doesn't add the non-terminating error to + the `$Error` automatic variable. The `Ignore` value is introduced in + PowerShell 3.0. - `Inquire` displays the error message and prompts you for confirmation before continuing execution. This value is rarely used. - `SilentlyContinue` suppresses the error message and continues executing the From 8ebe0df29b35d3ec287427190dbdc1491b39fc33 Mon Sep 17 00:00:00 2001 From: SufficientDaikon Date: Sun, 29 Mar 2026 02:00:44 +0200 Subject: [PATCH 08/10] Add about_Error_Handling to index; fix stale descriptions and dates - About.md: Add missing about_Error_Handling entry to topic index - About.md: Update about_Trap and about_Try_Catch_Finally descriptions to say "statement-terminating and script-terminating errors" - about_Try_Catch_Finally.md: Fix [07] link text to match target heading - Update ms.date on about_Trap, about_CommonParameters, about_Preference_Variables, everything-about-exceptions Co-Authored-By: Claude Opus 4.6 --- .../7.6/Microsoft.PowerShell.Core/About/About.md | 12 ++++++++++-- .../About/about_CommonParameters.md | 2 +- .../About/about_Preference_Variables.md | 2 +- .../Microsoft.PowerShell.Core/About/about_Trap.md | 2 +- .../About/about_Try_Catch_Finally.md | 4 ++-- .../learn/deep-dives/everything-about-exceptions.md | 2 +- 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/About.md b/reference/7.6/Microsoft.PowerShell.Core/About/About.md index 196121ec30fc..bd30220861af 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/About.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/About.md @@ -167,6 +167,13 @@ Provides access to the Windows environment variables. Describes how to access and manage environment variables in PowerShell. +### [about_Error_Handling](about_Error_Handling.md) + +Describes the three categories of PowerShell errors — non-terminating, +statement-terminating, and script-terminating — and explains how error +action preferences, `try/catch/trap`, and error state variables control +error handling behavior. + ### [about_Execution_Policies](about_Execution_Policies.md) Describes the PowerShell execution policies and explains how to manage them. @@ -594,12 +601,13 @@ default. ### [about_Trap](about_Trap.md) -Describes a keyword that handles a terminating error. +Describes a keyword that handles statement-terminating and script-terminating +errors. ### [about_Try_Catch_Finally](about_Try_Catch_Finally.md) Describes how to use the `try`, `catch`, and `finally` blocks to handle -terminating errors. +statement-terminating and script-terminating errors. ### [about_Type_Accelerators](about_Type_Accelerators.md) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md index f381103d5fe0..8cf6583a436b 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md @@ -1,7 +1,7 @@ --- description: Describes the parameters that can be used with any cmdlet. Locale: en-US -ms.date: 01/18/2026 +ms.date: 03/29/2026 no-loc: [Confirm, Debug, ErrorAction, ErrorVariable, InformationAction, InformationVariable, OutBuffer, OutVariable, PipelineVariable, ProgressAction, Verbose, WarningAction, WarningVariable, WhatIf] online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-7.6&WT.mc_id=ps-gethelp schema: 2.0.0 diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md index cdd9e6150c7e..6b1d65ff52b8 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md @@ -1,7 +1,7 @@ --- description: Variables that customize the behavior of PowerShell. Locale: en-US -ms.date: 12/01/2025 +ms.date: 03/29/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7.6&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Preference_Variables diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Trap.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Trap.md index a6e0b7396b6e..c6370485163b 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Trap.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Trap.md @@ -1,7 +1,7 @@ --- description: Describes a keyword that handles statement-terminating and script-terminating errors. Locale: en-US -ms.date: 01/13/2026 +ms.date: 03/29/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_trap?view=powershell-7.6&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Trap diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md index 4aef7ac61125..c3444c15eabe 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md @@ -32,8 +32,8 @@ block or `trap` statement. > [!NOTE] > `$ErrorActionPreference` can suppress `throw`. When set to > `SilentlyContinue` or `Ignore`, the error does not propagate and -> execution continues at the next statement. For details, see the -> [_throw_ suppression section][07] in **about_Error_Handling**. +> execution continues at the next statement. For details, see +> [Script-terminating errors][07] in **about_Error_Handling**. Use the `try` block to define a section of a script in which you want PowerShell to monitor for errors. When an error occurs within the `try` block, diff --git a/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md b/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md index 2e1d6408c7de..cbd63d57cdb9 100644 --- a/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md +++ b/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md @@ -1,7 +1,7 @@ --- description: Error handling is just part of life when it comes to writing code. ms.custom: contributor-KevinMarquette -ms.date: 06/20/2024 +ms.date: 03/29/2026 title: Everything you wanted to know about exceptions --- # Everything you wanted to know about exceptions From 087687fcd363afff0cf7e698d801932de30aad47 Mon Sep 17 00:00:00 2001 From: Sean Wheeler Date: Thu, 2 Apr 2026 13:40:29 -0500 Subject: [PATCH 09/10] Editorial changes - mostly formatting --- .../About/about_Automatic_Variables.md | 2 +- .../About/about_CommonParameters.md | 5 +- .../About/about_Error_Handling.md | 359 +++++++++++------- .../About/about_Preference_Variables.md | 16 +- .../About/about_Throw.md | 23 +- .../About/about_Trap.md | 2 +- .../About/about_Try_Catch_Finally.md | 20 +- .../deep-dives/everything-about-exceptions.md | 97 +++-- 8 files changed, 292 insertions(+), 232 deletions(-) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md index 0ebc43571798..14ac19a11121 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md @@ -1,7 +1,7 @@ --- description: Describes variables that store state information for PowerShell. These variables are created and maintained by PowerShell. Locale: en-US -ms.date: 02/10/2026 +ms.date: 04/02/2026 no-loc: [Reset, Current, Background, Blink, Bold, Foreground, Formatting, Hidden, Italic, Reset, Reverse, Underline, PSEventArgs, PSEventSubscriber, PSEdition] online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_automatic_variables?view=powershell-7.6&WT.mc_id=ps-gethelp schema: 2.0.0 diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md index 8cf6583a436b..03100aa3d29d 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md @@ -1,7 +1,7 @@ --- description: Describes the parameters that can be used with any cmdlet. Locale: en-US -ms.date: 03/29/2026 +ms.date: 04/02/2026 no-loc: [Confirm, Debug, ErrorAction, ErrorVariable, InformationAction, InformationVariable, OutBuffer, OutVariable, PipelineVariable, ProgressAction, Verbose, WarningAction, WarningVariable, WhatIf] online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-7.6&WT.mc_id=ps-gethelp schema: 2.0.0 @@ -106,8 +106,7 @@ the display of debugging messages when `$DebugPreference` isn't Determines how the cmdlet responds to a non-terminating error from the command. This parameter overrides the value of the `$ErrorActionPreference` variable for -non-terminating errors generated by the command, such as those from the -`Write-Error` cmdlet. +non-terminating errors generated by the command or the `Write-Error` cmdlet. ```yaml Type: ActionPreference diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md index 6008ab4b04ad..c605c0214129 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md @@ -15,8 +15,12 @@ them. ## Long description -PowerShell distinguishes three categories of errors: **non-terminating** -errors, **statement-terminating** errors, and **script-terminating** errors. +PowerShell distinguishes three categories of errors: + +- Non-terminating errors +- Statement-terminating errors +- Script-terminating errors + Understanding the distinction is essential for writing reliable scripts and modules, because each category has different default behavior and requires different handling techniques. @@ -28,7 +32,7 @@ which PowerShell tracks separately from its own error system. ### Non-terminating errors -A non-terminating error reports a problem but does not stop the pipeline. The +A non-terminating error reports a problem but doesn't stop the pipeline. The command continues processing subsequent input objects. Non-terminating errors are generated by: @@ -58,8 +62,8 @@ Statement-terminating errors are generated by: - The `$PSCmdlet.ThrowTerminatingError()` method in advanced functions and compiled cmdlets -- Engine errors such as `CommandNotFoundException` (calling a command that does - not exist) and `ParameterBindingException` (invalid parameter arguments) +- Engine errors such as `CommandNotFoundException` (calling a command that + doesn't exist) and `ParameterBindingException` (invalid parameter arguments) - .NET method calls that throw exceptions, such as `[int]::Parse('abc')` ```powershell @@ -71,14 +75,14 @@ Write-Output 'This still runs' Statement-terminating errors can be caught by `try/catch` and `trap`. > [!NOTE] -> `.ThrowTerminatingError()` does not consult the `-ErrorAction` parameter +> `.ThrowTerminatingError()` doesn't consult the `-ErrorAction` parameter > (except for the `Break` value, which enters the debugger). However, > `$ErrorActionPreference` _does_ apply to statement-terminating errors > through the engine's statement-level handler. For example, > `$ErrorActionPreference = 'SilentlyContinue'` can suppress a > statement-terminating error so that the script continues at the next -> statement. The `-ErrorAction` parameter cannot do this. For details, see -> [The $ErrorActionPreference asymmetry][09]. +> statement. The `-ErrorAction` parameter can't do this. For details, see +> [The $ErrorActionPreference asymmetry][05]. ### Script-terminating errors @@ -89,8 +93,8 @@ statement. Script-terminating errors are generated by: - The `throw` keyword - Parse errors (syntax errors that prevent the script from being compiled) - Non-terminating errors **escalated** by `-ErrorAction Stop` or - `$ErrorActionPreference = 'Stop'` in non-advanced contexts (see - [How escalation works][05]) + `$ErrorActionPreference = 'Stop'` in non-advanced contexts. For more + information, see [How escalation works][01]. - Certain critical engine failures ```powershell @@ -104,27 +108,27 @@ Test-Throw Write-Output 'This never runs either (unless caught)' ``` -The `throw` keyword generates a script-terminating error by default. -However, `$ErrorActionPreference` _can_ suppress `throw` when set to -`SilentlyContinue` or `Ignore`. When calling an advanced function with +The `throw` keyword generates a script-terminating error by default. However, +`$ErrorActionPreference` _can_ suppress `throw` when set to `SilentlyContinue` +or `Ignore`. When calling an advanced function with `-ErrorAction SilentlyContinue`, the parameter translates to a scope-local `$ErrorActionPreference` value, so it also suppresses `throw` inside that function. > [!NOTE] -> Even with `$ErrorActionPreference = 'Ignore'`, a `throw` that is suppressed -> still records an entry in `$Error`. The `Ignore` value only prevents -> `$Error` recording for **non-terminating** errors. +> Even with `$ErrorActionPreference = 'Ignore'`, a `throw` that's suppressed +> still records an entry in `$Error`. The `Ignore` value only prevents `$Error` +> recording for **non-terminating** errors. > [!IMPORTANT] -> The terms _statement-terminating_ and _script-terminating_ describe scope of -> impact, not severity. A statement-terminating error stops one statement. A -> script-terminating error stops the entire script and its callers. Both can be -> caught by `try/catch`. +> The terms _statement-terminating_ and _script-terminating_ describe the scope +> of impact, not the severity of the error. A statement-terminating error stops +> one statement. A script-terminating error stops the entire script and its +> callers. Both can be caught by `try/catch`. ### External program errors -External (native) programs do not participate in PowerShell's error system +External (native) programs don't participate in PowerShell's error system directly. They report failure through a non-zero exit code, which PowerShell stores in the `$LASTEXITCODE` automatic variable. @@ -141,20 +145,20 @@ By default, a non-zero exit code from a native program: - Does **not** generate an `ErrorRecord` in `$Error` - Does **not** trigger `catch` or `trap` -Starting in PowerShell 7.3, the -`$PSNativeCommandUseErrorActionPreference` -experimental preference variable, when set to `$true`, causes a non-zero exit -code to emit a **non-terminating error** whose message states the specific exit -code (a `NativeCommandExitException`). This error then respects -`$ErrorActionPreference`, so setting it to `Stop` promotes the error to a -script-terminating error that can be caught with `try`/`catch`. +PowerShell 7.3 added the experimental preference variable +`$PSNativeCommandUseErrorActionPreference`, which became a stable feature in +7.4. When you set this variable to `$true`, it causes a non-zero exit code to +emit a **non-terminating error** whose message states the specific exit code (a +`NativeCommandExitException`). This error respects `$ErrorActionPreference`, so +setting it to `Stop` promotes the error to a script-terminating error that can +be caught with `try`/`catch`. ## Error state variables PowerShell maintains several automatic variables that reflect the current error state. -### $? +### `$?` Contains `$true` if the last operation succeeded and `$false` if it produced any error (non-terminating or terminating). For native commands, `$?` is set @@ -165,45 +169,45 @@ Get-Item -Path 'C:\NoSuchFile.txt' 2>$null $? # False ``` -### $Error +### `$Error` An `ArrayList` that stores the most recent error records, with the most recent error at index `0`. The list holds up to `$MaximumErrorCount` entries (default 256). -All non-terminating and terminating errors are added to `$Error` unless -`-ErrorAction Ignore` is used on non-terminating errors, which prevents both -display and recording. For terminating errors, `Ignore` suppresses display but -still records the error in `$Error`. +All terminating errors are added to `$Error`. For terminating errors, `Ignore` +suppresses display but still records the error in `$Error`. All non-terminating +are added to `$Error` unless `-ErrorAction Ignore` is used on non-terminating +errors, which prevents both display and recording. -### $LASTEXITCODE +### `$LASTEXITCODE` Contains the exit code of the last native program that ran. A value of `0` conventionally indicates success. Any non-zero value indicates failure. This -variable is not affected by PowerShell cmdlet errors. +variable isn't affected by PowerShell cmdlet errors. -## Modifying error behavior +## Control error behavior -### The -ErrorAction common parameter +### The `-ErrorAction` common parameter The `-ErrorAction` common parameter overrides `$ErrorActionPreference` for a single command. It controls how PowerShell responds to **non-terminating** errors from that command. -| Value | Behavior | -|--------------------|---------------------------------------------------| -| `Continue` | Display the error and continue (default) | -| `SilentlyContinue` | Suppress display, add to `$Error`, continue | -| `Ignore` | Suppress display and do not add to `$Error` | -| `Stop` | **Escalate** to a terminating error (see [How escalation works][05]) | -| `Inquire` | Prompt the user for a decision | -| `Break` | Enter the debugger | +| Value | Behavior | +| ------------------ | -------------------------------------------------------------------- | +| `Continue` | Display the error and continue (default) | +| `SilentlyContinue` | Suppress display, add to `$Error`, continue | +| `Ignore` | Suppress display and don't add to `$Error` | +| `Stop` | **Escalate** to a terminating error (see [How escalation works][01]) | +| `Inquire` | Prompt the user for a decision | +| `Break` | Enter the debugger | -`-ErrorAction` does not change the behavior of errors generated by +`-ErrorAction` doesn't change the behavior of errors generated by `$PSCmdlet.ThrowTerminatingError()`. Those errors are always statement-terminating regardless of the caller's preference. -### The $ErrorActionPreference variable +### The `$ErrorActionPreference `variable The `$ErrorActionPreference` preference variable applies to all commands in the current scope and child scopes. It accepts the same values as `-ErrorAction`. @@ -232,42 +236,60 @@ following mechanism: The scope of the escalated error depends on context: -- In **non-advanced** scripts, functions, or script blocks, +- In **non-advanced** scripts, functions, or script blocks, setting `$ErrorActionPreference = 'Stop'` escalates to a **script-terminating** error. The error propagates up the call stack. - In **advanced** functions and script blocks (those with `[CmdletBinding()]`), - the error remains **statement-terminating**. Execution continues at the - next statement after the call. + the error remains **statement-terminating**. Execution continues at the next + statement after the call. - Passing `-ErrorAction Stop` to an advanced function has the same effect as setting `$ErrorActionPreference = 'Stop'` inside it, because `-ErrorAction` translates to a scope-local `$ErrorActionPreference` value. -```powershell -# NON-advanced: script-terminating ('after' does NOT print) -& { param() $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' } 2>$null -'after' - -# ADVANCED: statement-terminating ('after' DOES print) -& { [CmdletBinding()]param() $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' } 2>$null -'after' -``` - -```powershell -try { - # Without -ErrorAction Stop: non-terminating, catch does not fire - Write-Error 'This is non-terminating' - Write-Output 'Execution continues' -} catch { - Write-Output "Caught: $_" # Not reached -} - -try { - # With -ErrorAction Stop: escalated to terminating - Write-Error 'This becomes terminating' -ErrorAction Stop -} catch { - Write-Output "Caught: $_" # Reached -} -``` +### Escalation examples + +- NON-advanced: script-terminating ('after' does NOT print) + + ```powershell + & { + param() + $ErrorActionPreference = 'Stop' + Get-Item 'NoSuchPath' + } 2>$null + 'after' + ``` + +- ADVANCED: statement-terminating ('after' DOES print) + + ```powershell + & { + [CmdletBinding()] + param() + $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' + } 2>$null + 'after' + ``` + +- Without `-ErrorAction Stop`: non-terminating, catch doesn't run + + ```powershell + try { + Write-Error 'This is non-terminating' + Write-Output 'Execution continues' + } catch { + Write-Output "Caught: $_" # Not reached + } + ``` + +- With `-ErrorAction Stop`: escalated to terminating + + ```powershell + try { + Write-Error 'This becomes terminating' -ErrorAction Stop + } catch { + Write-Output "Caught: $_" # Reached + } + ``` Escalated errors can be caught by their original exception type. The engine unwraps the `ActionPreferenceStopException` to find the underlying exception: @@ -280,17 +302,17 @@ try { } ``` -### The $ErrorActionPreference asymmetry +### The `$ErrorActionPreference` asymmetry The `-ErrorAction` parameter and the `$ErrorActionPreference` variable behave -differently with terminating errors. This is an important asymmetry: +differently with terminating errors. It's important to understand this +asymmetry: -- **`-ErrorAction`** only affects **non-terminating** errors. When a cmdlet - calls `$PSCmdlet.ThrowTerminatingError()`, the `-ErrorAction` parameter is - ignored (except for `Break`, which enters the debugger). The error is always - thrown. +- `-ErrorAction` only affects **non-terminating** errors. When a cmdlet calls + `$PSCmdlet.ThrowTerminatingError()`, the `-ErrorAction` parameter is ignored + (except for `Break`, which enters the debugger). The error is always thrown. -- **`$ErrorActionPreference`** affects **both** non-terminating and +- `$ErrorActionPreference` affects **both** non-terminating and statement-terminating errors. The engine's statement-level error handler reads `$ErrorActionPreference` (not the `-ErrorAction` parameter) and can suppress a statement-terminating error when the value is `SilentlyContinue` @@ -319,15 +341,18 @@ $ErrorActionPreference = 'Continue' ``` > [!IMPORTANT] -> `$ErrorActionPreference` cannot suppress errors that have -> `SuppressPromptInInterpreter` set to `true` (such as -> `ActionPreferenceStopException` from `-ErrorAction Stop` escalation), -> errors inside PowerShell class methods, or `PipelineStoppedException`. -> These always propagate regardless of the preference variable. +> `$ErrorActionPreference` can't suppress errors that have +> `SuppressPromptInInterpreter` set to `true`. These always propagate +> regardless of the preference variable. Examples of this type of error +> include: +> +> - `ActionPreferenceStopException` from `-ErrorAction Stop` escalation +> - Errors inside PowerShell class methods +> - `PipelineStoppedException` -## Handling errors +## Handle errors -### try/catch/finally +### `try/catch/finally` Use `try/catch/finally` to handle statement-terminating and script-terminating errors. When an error occurs inside a `try` block, PowerShell searches for a @@ -355,9 +380,9 @@ terminating errors escalated by `-ErrorAction Stop` or `$ErrorActionPreference = 'Stop'` to propagate to the `catch` block. This is designed behavior, not a special case. -For full syntax details, see [about_Try_Catch_Finally][06]. +For full syntax details, see [about_Try_Catch_Finally][12]. -### trap +### `trap` The `trap` statement handles terminating errors at the scope level. When an error occurs anywhere in the enclosing scope, the `trap` block runs. @@ -378,14 +403,14 @@ NonsenseCommand # Trap fires, execution continues Write-Output 'This runs because the trap used continue' ``` -For full syntax details, see [about_Trap][07]. +For full syntax details, see [about_Trap][11]. ## Reporting errors in functions and scripts When writing functions and scripts, choose the error-reporting mechanism that matches the severity of the failure. -### Non-terminating: Write-Error +### Non-terminating - use `Write-Error` Use `Write-Error` when the function can continue processing other input. This is appropriate for pipeline functions that process multiple objects and @@ -409,39 +434,39 @@ function Test-Path-Safe { > In advanced functions (those with `[CmdletBinding()]`), use > `$PSCmdlet.WriteError()` instead of `Write-Error` to ensure that `$?` is > properly set to `$false` in the caller's scope. The `Write-Error` cmdlet -> does not always set `$?` correctly. +> doesn't always set `$?` correctly. -### Statement-terminating: $PSCmdlet.ThrowTerminatingError() +### Statement-terminating - use `$PSCmdlet.ThrowTerminatingError()` -Use `$PSCmdlet.ThrowTerminatingError()` when the function cannot continue at -all but the caller should decide how to handle the failure. This is the -recommended approach in advanced functions. +Use `$PSCmdlet.ThrowTerminatingError()` when the function can't continue at all +but the caller should decide how to handle the failure. This is the recommended +approach in advanced functions. ```powershell 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) - } + [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 + Get-Content $Path | ConvertFrom-Json } ``` After the error leaves the function, the caller treats it as a non-terminating error by default. The caller can escalate it with `-ErrorAction Stop`. -### Script-terminating: throw +### Script-terminating - use `throw` -Use `throw` when recovery is not possible and the entire script should stop. +Use `throw` when recovery isn't possible and the entire script should stop. ```powershell $config = Get-Content 'config.json' -ErrorAction SilentlyContinue | @@ -454,42 +479,84 @@ if (-not $config) { ### Which mechanism to use -| Situation | Mechanism | -|-----------|-----------| -| Processing multiple inputs; some may fail | `Write-Error` or `$PSCmdlet.WriteError()` | -| Function cannot continue; caller decides | `$PSCmdlet.ThrowTerminatingError()` | -| Entire script must stop immediately | `throw` | +- When processing multiple inputs where some may fail, use `Write-Error` or + `$PSCmdlet.WriteError()`. +- If the function can't continue, use `$PSCmdlet.ThrowTerminatingError()` and + let the caller decide how to handle it. +- If the entire script must stop immediately, use `throw`. ## Summary of error types -| Property | Non-terminating | Statement-terminating | Script-terminating | -|----------|----------------|----------------------|-------------------| -| Generated by | `Write-Error`, `WriteError()` | `ThrowTerminatingError()`, engine errors, .NET method exceptions, `-ErrorAction Stop` in advanced contexts | `throw`, parse errors, `-ErrorAction Stop` in non-advanced contexts | -| Scope of impact | Pipeline continues | Current statement stops; script continues | Call stack unwinds | -| Caught by `catch` | No (unless escalated) | Yes | Yes | -| Caught by `trap` | No (unless escalated) | Yes | Yes | -| Added to `$Error` | Yes (unless `Ignore`) | Yes | Yes | -| Sets `$?` to `$false` | Yes | Yes | Yes | -| Affected by `-ErrorAction` | Yes | No (`Break` only) | No | -| Affected by `$ErrorActionPreference` | Yes | Yes (can suppress) | `throw`: Yes (can suppress); escalated: depends on context | +The following tables summarize the properties and behaviors of the different +error types in PowerShell. + +### Non-terminating error + +[Non-terminating errors][02] can be generated by `Write-Error` or +`$PSCmdlet.WriteError()`. + +| Attribute | Description | +| ------------------------------------ | ------------------------------- | +| Scope of impact | Pipeline continues | +| Caught by `catch` | No (unless escalated) | +| Caught by `trap` | No (unless escalated) | +| Added to `$Error` | Yes (unless `Ignore`) | +| Sets `$?` to `$false` | Yes | +| Affected by `-ErrorAction` | Yes | +| Affected by `$ErrorActionPreference` | Yes | + +### Statement-terminating error + +[Statement-terminating errors][04] can be generated by +`ThrowTerminatingError()`, engine errors, .NET method exceptions, or +`-ErrorAction Stop` in advanced contexts. + +| Attribute | Description | +| ------------------------------------ | ----------------------------------------- | +| Scope of impact | Current statement stops; script continues | +| Caught by `catch` | Yes | +| Caught by `trap` | Yes | +| Added to `$Error` | Yes | +| Sets `$?` to `$false` | Yes | +| Affected by `-ErrorAction` | No (`Break` only) | +| Affected by `$ErrorActionPreference` | Yes (can suppress) | + +### Script-terminating error + +[Script-terminating errors][03] can be generated by `throw`, parse errors, or +`-ErrorAction Stop` in non-advanced contexts. + +| Attribute | Description | +| ------------------------------------ | ----------------------------- | +| Scope of impact | Call stack unwinds | +| Caught by `catch` | Yes | +| Caught by `trap` | Yes | +| Added to `$Error` | Yes | +| Sets `$?` to `$false` | Yes | +| Affected by `-ErrorAction` | No | +| Affected by `$ErrorActionPreference` | `throw`: Yes (can suppress) | +| Affected by `$ErrorActionPreference` | Escalated: depends on context | ## See also -- [about_Automatic_Variables][01] -- [about_CommonParameters][02] -- [about_Preference_Variables][03] -- [about_Output_Streams][04] -- [about_Throw][08] -- [about_Trap][07] -- [about_Try_Catch_Finally][06] +- [about_Automatic_Variables][06] +- [about_CommonParameters][07] +- [about_Preference_Variables][09] +- [about_Output_Streams][08] +- [about_Throw][10] +- [about_Trap][11] +- [about_Try_Catch_Finally][12] -[01]: about_Automatic_Variables.md -[02]: about_CommonParameters.md -[03]: about_Preference_Variables.md -[04]: about_Output_Streams.md -[05]: #how-escalation-works -[06]: about_Try_Catch_Finally.md -[07]: about_Trap.md -[08]: about_Throw.md -[09]: #the-erroractionpreference-asymmetry +[01]: #how-escalation-works +[02]: #non-terminating-errors +[03]: #script-terminating-errors +[04]: #statement-terminating-errors +[05]: #the-erroractionpreference-asymmetry +[06]: about_Automatic_Variables.md +[07]: about_CommonParameters.md +[08]: about_Output_Streams.md +[09]: about_Preference_Variables.md +[10]: about_Throw.md +[11]: about_Trap.md +[12]: about_Try_Catch_Finally.md diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md index 6b1d65ff52b8..7e76f45b7d26 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md @@ -1,7 +1,7 @@ --- description: Variables that customize the behavior of PowerShell. Locale: en-US -ms.date: 03/29/2026 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7.6&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Preference_Variables @@ -399,8 +399,8 @@ The valid values are as follows: - **SilentlyContinue**: No effect. The error message isn't displayed and execution continues without interruption. - **Stop**: Displays the error message and stops executing. In addition to the - error generated, the **Stop** value generates an ActionPreferenceStopException - object to the error stream. + error generated, the **Stop** value generates an + ActionPreferenceStopException object to the error stream. - **Suspend**: Automatically suspends a workflow job to allow for further investigation. After investigation, the workflow can be resumed. The **Suspend** value is intended for per-command use, not for use as saved @@ -410,11 +410,11 @@ The valid values are as follows: `$ErrorActionPreference` applies to **both** non-terminating and statement-terminating errors. Unlike the `-ErrorAction` parameter (which only affects non-terminating errors), the preference variable can also suppress or -escalate errors generated by `$PSCmdlet.ThrowTerminatingError()`. -When set to **Stop**, it escalates non-terminating errors to -script-terminating errors. For more information about error categories, see -[about_Error_Handling][67]. For more information about the **ErrorAction** -common parameter, see [about_CommonParameters][29]. +escalate errors generated by `$PSCmdlet.ThrowTerminatingError()`. When set to +**Stop**, it escalates non-terminating errors to script-terminating errors. For +more information about error categories, see [about_Error_Handling][67]. For +more information about the **ErrorAction** common parameter, see +[about_CommonParameters][29]. Many native commands write to `stderr` as an alternative stream for additional information. This behavior can cause confusion when looking through errors or diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md index 292aa1983243..cc223479c797 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md @@ -1,7 +1,7 @@ --- description: Describes the `throw` keyword, which generates a script-terminating error by default. Locale: en-US -ms.date: 03/29/2026 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_throw?view=powershell-7.6&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Throw @@ -10,7 +10,7 @@ title: about_Throw ## Short description -Describes the `throw` keyword that generates a script-terminating error by +Describes the `throw` keyword, which generates a script-terminating error by default. ## Long description @@ -18,20 +18,19 @@ default. The `throw` keyword causes a script-terminating error by default. You can use the `throw` keyword to stop the processing of a command, function, or script. -Unlike statement-terminating errors (generated by -`$PSCmdlet.ThrowTerminatingError()`), the `throw` keyword unwinds the entire +Unlike statement-terminating errors, the `throw` keyword unwinds the entire call stack. Execution stops completely unless the error is caught by a `try/catch` block or `trap` statement. > [!NOTE] -> `$ErrorActionPreference` can suppress `throw`. When set to -> `SilentlyContinue` or `Ignore`, the error does not propagate and -> execution continues at the next statement. When calling an advanced -> function with `-ErrorAction SilentlyContinue`, the parameter translates -> to a scope-local `$ErrorActionPreference` value, so it also suppresses -> `throw` inside that function. Even when suppressed, `throw` still records -> an entry in `$Error` — `Ignore` only prevents `$Error` recording for -> non-terminating errors. +> `$ErrorActionPreference` can suppress `throw`. When set to `SilentlyContinue` +> or `Ignore`, the error doesn't propagate and execution continues at the next +> statement. When calling an advanced function with +> `-ErrorAction SilentlyContinue`, the parameter translates to a scope-local +> `$ErrorActionPreference` value, so it also suppresses `throw` inside that +> function. Even when suppressed, `throw` still records an entry in `$Error`. +> The `Ignore` value only prevents `$Error` recording for non-terminating +> errors like those generated by `$PSCmdlet.ThrowTerminatingError()`. For more information about error categories and `$ErrorActionPreference` behavior, see [about_Error_Handling](about_Error_Handling.md). diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Trap.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Trap.md index c6370485163b..d740940722d8 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Trap.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Trap.md @@ -1,7 +1,7 @@ --- description: Describes a keyword that handles statement-terminating and script-terminating errors. Locale: en-US -ms.date: 03/29/2026 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_trap?view=powershell-7.6&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Trap diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md index c3444c15eabe..53c343547c5a 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md @@ -1,7 +1,7 @@ --- description: Describes how to use the `try`, `catch`, and `finally` blocks to handle statement-terminating and script-terminating errors. Locale: en-US -ms.date: 03/29/2026 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_try_catch_finally?view=powershell-7.6&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Try_Catch_Finally @@ -17,10 +17,12 @@ statement-terminating and script-terminating errors. Use `try`, `catch`, and `finally` blocks to respond to or handle terminating errors in scripts. PowerShell has two kinds of terminating errors: -_statement-terminating_ errors that stop the current statement and -_script-terminating_ errors that unwind the entire call stack. Both kinds are -caught by `try/catch`. The `trap` statement can also be used to handle -terminating errors. For more information, see [about_Trap][05]. For a + +- _statement-terminating_ errors that stop the current statement and +- _script-terminating_ errors that unwind the entire call stack + +Both kinds are caught by `try/catch`. You can also use the `trap` statement to +handle terminating errors. For more information, see [about_Trap][05]. For a comprehensive overview of all error types, see [about_Error_Handling][06]. A statement-terminating error stops the current statement from running, but @@ -30,10 +32,10 @@ the `throw` keyword) stops the entire script unless caught by a `try/catch` block or `trap` statement. > [!NOTE] -> `$ErrorActionPreference` can suppress `throw`. When set to -> `SilentlyContinue` or `Ignore`, the error does not propagate and -> execution continues at the next statement. For details, see -> [Script-terminating errors][07] in **about_Error_Handling**. +> `$ErrorActionPreference` can suppress `throw`. When set to `SilentlyContinue` +> or `Ignore`, the error doesn't propagate and execution continues at the next +> statement. For details, see the _Script-terminating errors_ section of +> [about_Error_Handling][07]. Use the `try` block to define a section of a script in which you want PowerShell to monitor for errors. When an error occurs within the `try` block, diff --git a/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md b/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md index cbd63d57cdb9..363d9f3e786e 100644 --- a/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md +++ b/reference/docs-conceptual/learn/deep-dives/everything-about-exceptions.md @@ -1,7 +1,7 @@ --- description: Error handling is just part of life when it comes to writing code. ms.custom: contributor-KevinMarquette -ms.date: 03/29/2026 +ms.date: 04/02/2026 title: Everything you wanted to know about exceptions --- # Everything you wanted to know about exceptions @@ -12,9 +12,9 @@ can easily handle exceptions generated by other people's code or you can generat exceptions for others to handle. > [!NOTE] -> The [original version][07] of this article appeared on the blog written by [@KevinMarquette][08]. +> The [original version][08] of this article appeared on the blog written by [@KevinMarquette][09]. > The PowerShell team thanks Kevin for sharing this content with us. Please check out his blog at -> [PowerShellExplained.com][05]. +> [PowerShellExplained.com][06]. ## Basic terminology @@ -44,16 +44,18 @@ it. ### Terminating and non-terminating errors -PowerShell has three categories of errors. A _non-terminating error_ (generated -by `Write-Error`) adds an error to the error stream without stopping execution -and does not trigger `catch`. A _statement-terminating error_ (generated by -`$PSCmdlet.ThrowTerminatingError()`, engine errors, or .NET method exceptions) -stops the current statement but allows the script to continue at the next -statement. A _script-terminating error_ (generated by `throw`, parse errors, or -`-ErrorAction Stop` escalation) unwinds the entire call stack. Both -statement-terminating and script-terminating errors can be caught by -`try/catch`. For a comprehensive reference, see -[about_Error_Handling](/powershell/module/microsoft.powershell.core/about/about_error_handling). +PowerShell has three categories of errors. + +- A _non-terminating error_ adds an error to the error stream without stopping execution and doesn't + trigger `catch`. By default, `Write-Error` generates non-terminating errors. +- A _statement-terminating error_ stops the current statement but allows the script to continue at + the next statement. Statement-terminating errors can be generated by engine errors, + `$PSCmdlet.ThrowTerminatingError()`, or .NET method exceptions. +- A _script-terminating error_ unwinds the entire call stack. Script-terminating errors can be + generated by `throw`, parse errors, or `-ErrorAction Stop` escalation. + +Both statement-terminating and script-terminating errors can be caught by `try/catch`. For a +comprehensive reference, see [about_Error_Handling][04]. ### Swallowing an exception @@ -111,7 +113,7 @@ Start-Something -ErrorAction Stop ``` For more information about the **ErrorAction** parameter, see [about_CommonParameters][03]. For more -information about the `$ErrorActionPreference` variable, see [about_Preference_Variables][04]. +information about the `$ErrorActionPreference` variable, see [about_Preference_Variables][05]. ### Try/Catch @@ -430,7 +432,7 @@ catch [System.IO.FileNotFoundException] I compiled a master list with the help of the Reddit `r/PowerShell` community that contains hundreds of .NET exceptions to complement this post. -- [The big list of .NET exceptions][06] +- [The big list of .NET exceptions][07] I start by searching that list for exceptions that feel like they would be a good fit for my situation. You should try to use exceptions in the base `System` namespace. @@ -562,57 +564,50 @@ the users of your Cmdlet. ## How try/catch changes error propagation -Inside a `try` block, PowerShell sets an internal flag that causes all -statement-terminating errors to propagate to the `catch` block. This is by -design, not a corner case. The following example demonstrates this behavior. - -Outside `try/catch`, a statement-terminating error from a child scope does not -stop the parent scope. Here is a function that generates a divide by zero -runtime exception. +Inside a `try` block, PowerShell sets an internal flag that causes all statement-terminating errors +to propagate to the `catch` block. This is by design, not a corner case. The following example +demonstrates this behavior. ```powershell function Start-Something { 1/(1-1) } ``` +Outside `try/catch`, a statement-terminating error from a child scope doesn't stop the parent scope. +Here is a function that generates a divide by zero runtime exception. + Invoke it like this to see the error reported while the script continues. ```powershell &{ Start-Something; Write-Output "We did it. Send Email" } ``` -But placing that same code inside a `try/catch`, the error propagates to the -`catch` block. +But placing that same code inside a `try/catch`, the error propagates to the `catch` block. ```powershell -try -{ +try { &{ Start-Something; Write-Output "We did it. Send Email" } -} -catch -{ +} catch { Write-Output "Notify Admin to fix error and send email" } ``` -The error is caught and the subsequent `Write-Output` inside the script block -does not run. This is standard `try/catch` behavior — all terminating errors -within the `try` block are caught, whether they originate in the current scope -or in a child scope. +The error is caught and the subsequent `Write-Output` inside the script block doesn't run. This is +standard `try/catch` behavior — all terminating errors within the `try` block are caught, whether +they originate in the current scope or in a child scope. ### $PSCmdlet.ThrowTerminatingError() inside try/catch -`$PSCmdlet.ThrowTerminatingError()` creates a statement-terminating error -within the cmdlet. After the error leaves the cmdlet, the caller treats it as a -non-terminating error by default. The caller can escalate it back to a -terminating error by using `-ErrorAction Stop` or calling it from within a -`try{...}catch{...}`. +`$PSCmdlet.ThrowTerminatingError()` creates a statement-terminating error within the cmdlet. After +the error leaves the cmdlet, the caller treats it as a non-terminating error by default. The caller +can escalate it back to a terminating error by using `-ErrorAction Stop` or calling it from within a +`try/catch` block. ### Public function templates -One last takeaway I had with my conversation with Kirk Munro was that he places a -`try{...}catch{...}` around every `begin`, `process` and `end` block in all of his advanced -functions. In those generic catch blocks, he has a single line using -`$PSCmdlet.ThrowTerminatingError($PSItem)` to deal with all exceptions leaving his functions. +One last takeaway I had with my conversation with Kirk Munro was that he places a `try/catch` block +inside every `begin`, `process` and `end` block in all his advanced functions. In those generic +catch blocks, he has a single line using `$PSCmdlet.ThrowTerminatingError($PSItem)` to deal with all +exceptions leaving his functions. ```powershell function Start-Something @@ -622,12 +617,9 @@ function Start-Something process { - try - { + try { ... - } - catch - { + } catch { $PSCmdlet.ThrowTerminatingError($PSItem) } } @@ -677,8 +669,9 @@ advice and make `ThrowTerminatingError` my goto exception handler for every func [01]: /dotnet/api [02]: /dotnet/api/System.IO.FileNotFoundException [03]: /powershell/module/microsoft.powershell.core/about/about_commonparameters -[04]: /powershell/module/microsoft.powershell.core/about/about_preference_variables -[05]: https://powershellexplained.com/ -[06]: https://powershellexplained.com/2017-04-07-all-dotnet-exception-list -[07]: https://powershellexplained.com/2017-04-10-Powershell-exceptions-everything-you-ever-wanted-to-know/ -[08]: https://twitter.com/KevinMarquette +[04]: /powershell/module/microsoft.powershell.core/about/about_error_handling +[05]: /powershell/module/microsoft.powershell.core/about/about_preference_variables +[06]: https://powershellexplained.com/ +[07]: https://powershellexplained.com/2017-04-07-all-dotnet-exception-list +[08]: https://powershellexplained.com/2017-04-10-Powershell-exceptions-everything-you-ever-wanted-to-know/ +[09]: https://twitter.com/KevinMarquette From 8cc25cb37aca1dde2d7ed0ede57f0df6cb7f70f8 Mon Sep 17 00:00:00 2001 From: Sean Wheeler Date: Thu, 2 Apr 2026 14:58:54 -0500 Subject: [PATCH 10/10] Copy changes to all versions --- .../About/about_Automatic_Variables.md | 6 +- .../About/about_CommonParameters.md | 20 +- .../About/about_Error_Handling.md | 562 ++++++++++++++++++ .../About/about_Preference_Variables.md | 50 +- .../About/about_Throw.md | 52 +- .../About/about_Trap.md | 36 +- .../About/about_Try_Catch_Finally.md | 36 +- .../About/about_Automatic_Variables.md | 6 +- .../About/about_CommonParameters.md | 26 +- .../About/about_Error_Handling.md | 562 ++++++++++++++++++ .../About/about_Preference_Variables.md | 34 +- .../About/about_Throw.md | 52 +- .../About/about_Trap.md | 20 +- .../About/about_Try_Catch_Finally.md | 36 +- .../About/about_Automatic_Variables.md | 6 +- .../About/about_CommonParameters.md | 26 +- .../About/about_Error_Handling.md | 562 ++++++++++++++++++ .../About/about_Preference_Variables.md | 34 +- .../About/about_Throw.md | 52 +- .../About/about_Trap.md | 20 +- .../About/about_Try_Catch_Finally.md | 36 +- .../About/about_Preference_Variables.md | 7 +- .../About/about_Throw.md | 27 +- 23 files changed, 2080 insertions(+), 188 deletions(-) create mode 100644 reference/5.1/Microsoft.PowerShell.Core/About/about_Error_Handling.md create mode 100644 reference/7.4/Microsoft.PowerShell.Core/About/about_Error_Handling.md create mode 100644 reference/7.5/Microsoft.PowerShell.Core/About/about_Error_Handling.md diff --git a/reference/5.1/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md b/reference/5.1/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md index aa6467ae692f..86336446e0ac 100644 --- a/reference/5.1/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md +++ b/reference/5.1/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md @@ -1,7 +1,7 @@ --- description: Describes variables that store state information for PowerShell. These variables are created and maintained by PowerShell. Locale: en-US -ms.date: 02/10/2026 +ms.date: 04/02/2026 no-loc: [Reset, Current, Background, Blink, Bold, Foreground, Formatting, Hidden, Italic, Reset, Reverse, Underline, PSEventArgs, PSEventSubscriber, PSEdition] online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_automatic_variables?view=powershell-5.1&WT.mc_id=ps-gethelp schema: 2.0.0 @@ -160,8 +160,8 @@ use this automatic variable to determine the file to update. Contains an array of error objects that represent the most recent errors. The most recent error is the first error object in the array `$Error[0]`. -To prevent an error from being added to the `$Error` array, use the -**ErrorAction** common parameter with a value of **Ignore**. For more +To prevent a non-terminating error from being added to the `$Error` array, use +the **ErrorAction** common parameter with a value of **Ignore**. For more information, see [about_CommonParameters][53]. ### `$Event` diff --git a/reference/5.1/Microsoft.PowerShell.Core/About/about_CommonParameters.md b/reference/5.1/Microsoft.PowerShell.Core/About/about_CommonParameters.md index fe32c56dd06d..c8aa37643dcd 100644 --- a/reference/5.1/Microsoft.PowerShell.Core/About/about_CommonParameters.md +++ b/reference/5.1/Microsoft.PowerShell.Core/About/about_CommonParameters.md @@ -1,7 +1,7 @@ --- description: Describes the parameters that can be used with any cmdlet. Locale: en-US -ms.date: 01/18/2026 +ms.date: 04/02/2026 no-loc: [Confirm, Debug, ErrorAction, ErrorVariable, InformationAction, InformationVariable, OutBuffer, OutVariable, PipelineVariable, ProgressAction, Verbose, WarningAction, WarningVariable, WhatIf] online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-5.1&WT.mc_id=ps-gethelp schema: 2.0.0 @@ -109,14 +109,13 @@ the display of debugging messages when `$DebugPreference` isn't ### -ErrorAction Determines how the cmdlet responds to a non-terminating error from the command. -This parameter works only when the command generates a non-terminating error, -such as those from the `Write-Error` cmdlet. +This parameter overrides the value of the `$ErrorActionPreference` variable for +non-terminating errors generated by the command or the `Write-Error` cmdlet. ```yaml Type: ActionPreference Aliases: ea -Accepted values: Suspend, Ignore, Inquire, Continue, Stop, SilentlyContinue - +Accepted values: Break, Suspend, Ignore, Inquire, Continue, Stop, SilentlyContinue Required: False Position: Named Default value: Depends on preference variable @@ -129,9 +128,12 @@ variable for the current command. Because the default value of the `$ErrorActionPreference` variable is `Continue`, error messages are displayed and execution continues unless you use the `ErrorAction` parameter. -The `ErrorAction` parameter has no effect on terminating errors (such as -missing data, parameters that aren't valid, or insufficient permissions) that -prevent a command from completing successfully. +The `-ErrorAction` parameter doesn't prevent statement-terminating errors +(such as missing data, parameters that aren't valid, or insufficient +permissions) from stopping the current statement. However, when set to `Stop`, +it escalates non-terminating errors to script-terminating errors, making them +catchable by `try/catch`. For more information about error categories, see +[about_Error_Handling][15]. - `-ErrorAction:Break` Enters the debugger when an error occurs or an exception is raised. @@ -829,6 +831,7 @@ Mode LastWriteTime Length Name - [about_Preference_Variables][03] +- [about_Error_Handling][15] - [`Write-Debug`][11] - [`Write-Error`][12] - [`Write-Verbose`][13] @@ -844,4 +847,5 @@ Mode LastWriteTime Length Name [12]: xref:Microsoft.PowerShell.Utility.Write-Error [13]: xref:Microsoft.PowerShell.Utility.Write-Verbose [14]: xref:Microsoft.PowerShell.Utility.Write-Warning +[15]: about_Error_Handling.md diff --git a/reference/5.1/Microsoft.PowerShell.Core/About/about_Error_Handling.md b/reference/5.1/Microsoft.PowerShell.Core/About/about_Error_Handling.md new file mode 100644 index 000000000000..b7f5428356e6 --- /dev/null +++ b/reference/5.1/Microsoft.PowerShell.Core/About/about_Error_Handling.md @@ -0,0 +1,562 @@ +--- +description: Describes the types of errors in PowerShell and the mechanisms for handling them. +Locale: en-US +ms.date: 03/26/2026 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_error_handling?view=powershell-5.1&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Error_Handling +--- +# about_Error_Handling + +## Short description + +Describes the types of errors in PowerShell and the mechanisms for handling +them. + +## Long description + +PowerShell distinguishes three categories of errors: + +- Non-terminating errors +- Statement-terminating errors +- Script-terminating errors + +Understanding the distinction is essential for writing reliable scripts and +modules, because each category has different default behavior and requires +different handling techniques. + +Additionally, external (native) programs report failure through exit codes, +which PowerShell tracks separately from its own error system. + +## Types of errors + +### Non-terminating errors + +A non-terminating error reports a problem but doesn't stop the pipeline. The +command continues processing subsequent input objects. Non-terminating errors +are generated by: + +- The `Write-Error` cmdlet +- The `$PSCmdlet.WriteError()` method in advanced functions +- Cmdlets that encounter recoverable failures on individual input objects + +By default, PowerShell displays the error message and continues execution. + +```powershell +# Non-terminating error: the pipeline continues after the failure +'file1.txt', 'noSuchFile.txt', 'file3.txt' | ForEach-Object { + Get-Content $_ -ErrorAction Continue +} +``` + +In this example, `Get-Content` reports a non-terminating error for +`noSuchFile.txt` and then continues processing `file3.txt`. + +Non-terminating errors do **not** trigger `catch` or `trap` by default. + +### Statement-terminating errors + +A statement-terminating error stops the current statement (pipeline) from +running, but execution continues at the next statement in the script. +Statement-terminating errors are generated by: + +- The `$PSCmdlet.ThrowTerminatingError()` method in advanced functions and + compiled cmdlets +- Engine errors such as `CommandNotFoundException` (calling a command that + doesn't exist) and `ParameterBindingException` (invalid parameter arguments) +- .NET method calls that throw exceptions, such as `[int]::Parse('abc')` + +```powershell +# Statement-terminating error: Get-Item fails, but the next statement runs +Get-Item -Path 'C:\NoSuchFile.txt' +Write-Output 'This still runs' +``` + +Statement-terminating errors can be caught by `try/catch` and `trap`. + +> [!NOTE] +> `.ThrowTerminatingError()` doesn't consult the `-ErrorAction` parameter +> (except for the `Break` value, which enters the debugger). However, +> `$ErrorActionPreference` _does_ apply to statement-terminating errors +> through the engine's statement-level handler. For example, +> `$ErrorActionPreference = 'SilentlyContinue'` can suppress a +> statement-terminating error so that the script continues at the next +> statement. The `-ErrorAction` parameter can't do this. For details, see +> [The $ErrorActionPreference asymmetry][05]. + +### Script-terminating errors + +A script-terminating error unwinds the entire call stack. Execution stops +completely unless the error is caught by a `try/catch` block or `trap` +statement. Script-terminating errors are generated by: + +- The `throw` keyword +- Parse errors (syntax errors that prevent the script from being compiled) +- Non-terminating errors **escalated** by `-ErrorAction Stop` or + `$ErrorActionPreference = 'Stop'` in non-advanced contexts. For more + information, see [How escalation works][01]. +- Certain critical engine failures + +```powershell +# 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)' +``` + +The `throw` keyword generates a script-terminating error by default. However, +`$ErrorActionPreference` _can_ suppress `throw` when set to `SilentlyContinue` +or `Ignore`. When calling an advanced function with +`-ErrorAction SilentlyContinue`, the parameter translates to a scope-local +`$ErrorActionPreference` value, so it also suppresses `throw` inside that +function. + +> [!NOTE] +> Even with `$ErrorActionPreference = 'Ignore'`, a `throw` that's suppressed +> still records an entry in `$Error`. The `Ignore` value only prevents `$Error` +> recording for **non-terminating** errors. + +> [!IMPORTANT] +> The terms _statement-terminating_ and _script-terminating_ describe the scope +> of impact, not the severity of the error. A statement-terminating error stops +> one statement. A script-terminating error stops the entire script and its +> callers. Both can be caught by `try/catch`. + +### External program errors + +External (native) programs don't participate in PowerShell's error system +directly. They report failure through a non-zero exit code, which PowerShell +stores in the `$LASTEXITCODE` automatic variable. + +```powershell +git clone https://example.com/nonexistent.git 2>$null +if ($LASTEXITCODE -ne 0) { + Write-Error "git failed with exit code $LASTEXITCODE" +} +``` + +By default, a non-zero exit code from a native program: + +- Sets `$?` to `$false` +- Does **not** generate an `ErrorRecord` in `$Error` +- Does **not** trigger `catch` or `trap` + +PowerShell 7.3 added the experimental preference variable +`$PSNativeCommandUseErrorActionPreference`, which became a stable feature in +7.4. When you set this variable to `$true`, it causes a non-zero exit code to +emit a **non-terminating error** whose message states the specific exit code (a +`NativeCommandExitException`). This error respects `$ErrorActionPreference`, so +setting it to `Stop` promotes the error to a script-terminating error that can +be caught with `try`/`catch`. + +## Error state variables + +PowerShell maintains several automatic variables that reflect the current error +state. + +### `$?` + +Contains `$true` if the last operation succeeded and `$false` if it produced +any error (non-terminating or terminating). For native commands, `$?` is set +based on the exit code: `$true` for exit code `0`, `$false` otherwise. + +```powershell +Get-Item -Path 'C:\NoSuchFile.txt' 2>$null +$? # False +``` + +### `$Error` + +An `ArrayList` that stores the most recent error records, with the most recent +error at index `0`. The list holds up to `$MaximumErrorCount` entries (default +256). + +All terminating errors are added to `$Error`. For terminating errors, `Ignore` +suppresses display but still records the error in `$Error`. All non-terminating +are added to `$Error` unless `-ErrorAction Ignore` is used on non-terminating +errors, which prevents both display and recording. + +### `$LASTEXITCODE` + +Contains the exit code of the last native program that ran. A value of `0` +conventionally indicates success. Any non-zero value indicates failure. This +variable isn't affected by PowerShell cmdlet errors. + +## Control error behavior + +### The `-ErrorAction` common parameter + +The `-ErrorAction` common parameter overrides `$ErrorActionPreference` for a +single command. It controls how PowerShell responds to **non-terminating** +errors from that command. + +| Value | Behavior | +| ------------------ | -------------------------------------------------------------------- | +| `Continue` | Display the error and continue (default) | +| `SilentlyContinue` | Suppress display, add to `$Error`, continue | +| `Ignore` | Suppress display and don't add to `$Error` | +| `Stop` | **Escalate** to a terminating error (see [How escalation works][01]) | +| `Inquire` | Prompt the user for a decision | +| `Break` | Enter the debugger | + +`-ErrorAction` doesn't change the behavior of errors generated by +`$PSCmdlet.ThrowTerminatingError()`. Those errors are always +statement-terminating regardless of the caller's preference. + +### The `$ErrorActionPreference `variable + +The `$ErrorActionPreference` preference variable applies to all commands in the +current scope and child scopes. It accepts the same values as `-ErrorAction`. + +```powershell +$ErrorActionPreference = 'Stop' +# All non-terminating errors in this scope now become terminating +Write-Error 'This now throws' # Generates ActionPreferenceStopException +``` + +When `-ErrorAction` is specified on a command, it takes precedence over +`$ErrorActionPreference` for that command. + +### How escalation works + +When `-ErrorAction Stop` or `$ErrorActionPreference = 'Stop'` is in effect, +PowerShell converts non-terminating errors into terminating errors using the +following mechanism: + +1. A cmdlet calls `WriteError()` internally to emit a non-terminating error. +1. The engine checks the effective `ErrorAction` preference for the command. +1. Because the preference is `Stop`, the engine creates an + `ActionPreferenceStopException` that wraps the original error record. +1. If caught by `catch`, the original error information is accessible through + `$_.Exception.ErrorRecord`. + +The scope of the escalated error depends on context: + +- In **non-advanced** scripts, functions, or script blocks, setting + `$ErrorActionPreference = 'Stop'` escalates to a **script-terminating** + error. The error propagates up the call stack. +- In **advanced** functions and script blocks (those with `[CmdletBinding()]`), + the error remains **statement-terminating**. Execution continues at the next + statement after the call. +- Passing `-ErrorAction Stop` to an advanced function has the same effect as + setting `$ErrorActionPreference = 'Stop'` inside it, because `-ErrorAction` + translates to a scope-local `$ErrorActionPreference` value. + +### Escalation examples + +- NON-advanced: script-terminating ('after' does NOT print) + + ```powershell + & { + param() + $ErrorActionPreference = 'Stop' + Get-Item 'NoSuchPath' + } 2>$null + 'after' + ``` + +- ADVANCED: statement-terminating ('after' DOES print) + + ```powershell + & { + [CmdletBinding()] + param() + $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' + } 2>$null + 'after' + ``` + +- Without `-ErrorAction Stop`: non-terminating, catch doesn't run + + ```powershell + try { + Write-Error 'This is non-terminating' + Write-Output 'Execution continues' + } catch { + Write-Output "Caught: $_" # Not reached + } + ``` + +- With `-ErrorAction Stop`: escalated to terminating + + ```powershell + try { + Write-Error 'This becomes terminating' -ErrorAction Stop + } catch { + Write-Output "Caught: $_" # Reached + } + ``` + +Escalated errors can be caught by their original exception type. The engine +unwraps the `ActionPreferenceStopException` to find the underlying exception: + +```powershell +try { + Get-Item -Path 'C:\NoSuchFile.txt' -ErrorAction Stop +} catch [System.Management.Automation.ItemNotFoundException] { + Write-Output "File not found: $($_.Exception.Message)" +} +``` + +### The `$ErrorActionPreference` asymmetry + +The `-ErrorAction` parameter and the `$ErrorActionPreference` variable behave +differently with terminating errors. It's important to understand this +asymmetry: + +- `-ErrorAction` only affects **non-terminating** errors. When a cmdlet calls + `$PSCmdlet.ThrowTerminatingError()`, the `-ErrorAction` parameter is ignored + (except for `Break`, which enters the debugger). The error is always thrown. + +- `$ErrorActionPreference` affects **both** non-terminating and + statement-terminating errors. The engine's statement-level error handler + reads `$ErrorActionPreference` (not the `-ErrorAction` parameter) and can + suppress a statement-terminating error when the value is `SilentlyContinue` + or `Ignore`. + +```powershell +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' +``` + +> [!IMPORTANT] +> `$ErrorActionPreference` can't suppress errors that have +> `SuppressPromptInInterpreter` set to `true`. These always propagate +> regardless of the preference variable. Examples of this type of error +> include: +> +> - `ActionPreferenceStopException` from `-ErrorAction Stop` escalation +> - Errors inside PowerShell class methods +> - `PipelineStoppedException` + +## Handle errors + +### `try/catch/finally` + +Use `try/catch/finally` to handle statement-terminating and script-terminating +errors. When an error occurs inside a `try` block, PowerShell searches for a +matching `catch` block. The `finally` block always runs, whether or not an +error occurred. + +```powershell +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 +} +``` + +Inside a `try` block, the engine sets an internal flag that causes non- +terminating errors escalated by `-ErrorAction Stop` or +`$ErrorActionPreference = 'Stop'` to propagate to the `catch` block. This +is designed behavior, not a special case. + +For full syntax details, see [about_Try_Catch_Finally][12]. + +### `trap` + +The `trap` statement handles terminating errors at the scope level. When an +error occurs anywhere in the enclosing scope, the `trap` block runs. + +- **Default** (no `break` or `continue`): The error is displayed and execution + continues at the next statement after the one that caused the error. +- **`continue`** in the trap: Suppresses the error message and resumes at the + next statement. +- **`break`** in the trap: The error propagates to the parent scope. + +```powershell +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' +``` + +For full syntax details, see [about_Trap][11]. + +## Reporting errors in functions and scripts + +When writing functions and scripts, choose the error-reporting mechanism that +matches the severity of the failure. + +### Non-terminating - use `Write-Error` + +Use `Write-Error` when the function can continue processing other input. This +is appropriate for pipeline functions that process multiple objects and +encounter failures on individual items. + +```powershell +function Test-Path-Safe { + [CmdletBinding()] + param([Parameter(ValueFromPipeline)][string]$Path) + process { + if (-not (Test-Path $Path)) { + Write-Error "Path not found: $Path" + return + } + $Path + } +} +``` + +> [!NOTE] +> In advanced functions (those with `[CmdletBinding()]`), use +> `$PSCmdlet.WriteError()` instead of `Write-Error` to ensure that `$?` is +> properly set to `$false` in the caller's scope. The `Write-Error` cmdlet +> doesn't always set `$?` correctly. + +### Statement-terminating - use `$PSCmdlet.ThrowTerminatingError()` + +Use `$PSCmdlet.ThrowTerminatingError()` when the function can't continue at all +but the caller should decide how to handle the failure. This is the recommended +approach in advanced functions. + +```powershell +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 +} +``` + +After the error leaves the function, the caller treats it as a non-terminating +error by default. The caller can escalate it with `-ErrorAction Stop`. + +### Script-terminating - use `throw` + +Use `throw` when recovery isn't possible and the entire script should stop. + +```powershell +$config = Get-Content 'config.json' -ErrorAction SilentlyContinue | + ConvertFrom-Json + +if (-not $config) { + throw 'Cannot proceed without a valid configuration file.' +} +``` + +### Which mechanism to use + +- When processing multiple inputs where some may fail, use `Write-Error` or + `$PSCmdlet.WriteError()`. +- If the function can't continue, use `$PSCmdlet.ThrowTerminatingError()` and + let the caller decide how to handle it. +- If the entire script must stop immediately, use `throw`. + +## Summary of error types + +The following tables summarize the properties and behaviors of the different +error types in PowerShell. + +### Non-terminating error + +[Non-terminating errors][02] can be generated by `Write-Error` or +`$PSCmdlet.WriteError()`. + +| Attribute | Description | +| ------------------------------------ | ------------------------------- | +| Scope of impact | Pipeline continues | +| Caught by `catch` | No (unless escalated) | +| Caught by `trap` | No (unless escalated) | +| Added to `$Error` | Yes (unless `Ignore`) | +| Sets `$?` to `$false` | Yes | +| Affected by `-ErrorAction` | Yes | +| Affected by `$ErrorActionPreference` | Yes | + +### Statement-terminating error + +[Statement-terminating errors][04] can be generated by +`ThrowTerminatingError()`, engine errors, .NET method exceptions, or +`-ErrorAction Stop` in advanced contexts. + +| Attribute | Description | +| ------------------------------------ | ----------------------------------------- | +| Scope of impact | Current statement stops; script continues | +| Caught by `catch` | Yes | +| Caught by `trap` | Yes | +| Added to `$Error` | Yes | +| Sets `$?` to `$false` | Yes | +| Affected by `-ErrorAction` | No (`Break` only) | +| Affected by `$ErrorActionPreference` | Yes (can suppress) | + +### Script-terminating error + +[Script-terminating errors][03] can be generated by `throw`, parse errors, or +`-ErrorAction Stop` in non-advanced contexts. + +| Attribute | Description | +| ------------------------------------ | ----------------------------- | +| Scope of impact | Call stack unwinds | +| Caught by `catch` | Yes | +| Caught by `trap` | Yes | +| Added to `$Error` | Yes | +| Sets `$?` to `$false` | Yes | +| Affected by `-ErrorAction` | No | +| Affected by `$ErrorActionPreference` | `throw`: Yes (can suppress) | +| Affected by `$ErrorActionPreference` | Escalated: depends on context | + +## See also + +- [about_Automatic_Variables][06] +- [about_CommonParameters][07] +- [about_Preference_Variables][09] +- [about_Output_Streams][08] +- [about_Throw][10] +- [about_Trap][11] +- [about_Try_Catch_Finally][12] + + +[01]: #how-escalation-works +[02]: #non-terminating-errors +[03]: #script-terminating-errors +[04]: #statement-terminating-errors +[05]: #the-erroractionpreference-asymmetry +[06]: about_Automatic_Variables.md +[07]: about_CommonParameters.md +[08]: about_Output_Streams.md +[09]: about_Preference_Variables.md +[10]: about_Throw.md +[11]: about_Trap.md +[12]: about_Try_Catch_Finally.md diff --git a/reference/5.1/Microsoft.PowerShell.Core/About/about_Preference_Variables.md b/reference/5.1/Microsoft.PowerShell.Core/About/about_Preference_Variables.md index 5c8102aecaab..08fe9c6a869d 100644 --- a/reference/5.1/Microsoft.PowerShell.Core/About/about_Preference_Variables.md +++ b/reference/5.1/Microsoft.PowerShell.Core/About/about_Preference_Variables.md @@ -1,7 +1,7 @@ --- description: Variables that customize the behavior of PowerShell. Locale: en-US -ms.date: 12/01/2025 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-5.1&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Preference_Variables @@ -121,7 +121,8 @@ Cmdlets and functions are assigned a risk of **High**, **Medium**, or **Low**. When the value of the `$ConfirmPreference` variable is less than or equal to the risk assigned to a cmdlet or function, PowerShell automatically prompts you for confirmation before running the cmdlet or function. For more information -about assigning a risk to cmdlets or functions, see [about_Functions_CmdletBindingAttribute][65]. +about assigning a risk to cmdlets or functions, see +[about_Functions_CmdletBindingAttribute][65]. If the value of the `$ConfirmPreference` variable is **None**, PowerShell never automatically prompts you before running a cmdlet or function. @@ -169,11 +170,12 @@ Cmdlets and functions that might pose a risk to the system have a **Confirm** parameter that you can use to request or suppress confirmation for a single command. -Most cmdlets and functions keep the default value of **Medium** for **ConfirmImpact**. -`$ConfirmPreference` is set to **High** by default. Therefore, it's rare that commands -automatically prompt for confirmation when users don't specify the **Confirm** parameter. -To extend automatic confirmation prompting to more cmdlets and functions, set the value -of `$ConfirmPreference` to **Medium** or **Low**. +Most cmdlets and functions keep the default value of **Medium** for +**ConfirmImpact**. `$ConfirmPreference` is set to **High** by default. +Therefore, it's rare that commands automatically prompt for confirmation when +users don't specify the **Confirm** parameter. To extend automatic confirmation +prompting to more cmdlets and functions, set the value of `$ConfirmPreference` +to **Medium** or **Low**. ### Examples @@ -379,9 +381,8 @@ script, cmdlet, or provider, such as the errors generated by the `Write-Error` cmdlet. The `$ErrorActionPreference` variable takes one of the -[`ActionPreference`][54] -enumeration values: **SilentlyContinue**, **Stop**, **Continue**, **Inquire**, -**Ignore**, or **Suspend**. +[`ActionPreference`][54] enumeration values: **SilentlyContinue**, **Stop**, +**Continue**, **Inquire**, **Ignore**, or **Suspend**. You can use a cmdlet's **ErrorAction** common parameter to override the preference for a specific command. @@ -390,27 +391,39 @@ The valid values are as follows: - **Continue**: (Default) Displays the error message and continues executing. - **Ignore**: Suppresses the error message and continues to execute the - command. The **Ignore** value is intended for per-command use, not for use as - saved preference. **Ignore** isn't a valid value for the - `$ErrorActionPreference` variable. + command. Unlike **SilentlyContinue**, **Ignore** doesn't add the error + message to the `$Error` automatic variable. The **Ignore** value is also + valid for `$ErrorActionPreference`, where it suppresses both non-terminating + and statement-terminating errors. However, **Ignore** only prevents `$Error` + recording for non-terminating errors. Terminating errors that are suppressed + by `Ignore` are still recorded in `$Error`. - **Inquire**: Displays the error message and asks you whether you want to continue. - **SilentlyContinue**: No effect. The error message isn't displayed and execution continues without interruption. - **Stop**: Displays the error message and stops executing. In addition to the - error generated, the **Stop** value generates an ActionPreferenceStopException - object to the error stream. + error generated, the **Stop** value generates an + ActionPreferenceStopException object to the error stream. - **Suspend**: Automatically suspends a workflow job to allow for further investigation. After investigation, the workflow can be resumed. The **Suspend** value is intended for per-command use, not for use as saved preference. **Suspend** isn't a valid value for the `$ErrorActionPreference` variable. -`$ErrorActionPreference` and the **ErrorAction** parameter don't affect how -PowerShell responds to terminating errors that stop cmdlet processing. For more -information about the **ErrorAction** common parameter, see +`$ErrorActionPreference` applies to **both** non-terminating and +statement-terminating errors. Unlike the `-ErrorAction` parameter (which only +affects non-terminating errors), the preference variable can also suppress or +escalate errors generated by `$PSCmdlet.ThrowTerminatingError()`. When set to +**Stop**, it escalates non-terminating errors to script-terminating errors. For +more information about error categories, see [about_Error_Handling][67]. For +more information about the **ErrorAction** common parameter, see [about_CommonParameters][29]. +Many native commands write to `stderr` as an alternative stream for additional +information. This behavior can cause confusion when looking through errors or +the additional output information can be lost to the user if +`$ErrorActionPreference` is set to a state that mutes the output. + ### Examples These examples show the effect of the different values of the @@ -1775,3 +1788,4 @@ At line:1 char:1 [63]: xref:System.Text.UTF7Encoding [64]: xref:System.Text.UTF8Encoding [65]: about_Functions_CmdletBindingAttribute.md +[67]: about_Error_Handling.md diff --git a/reference/5.1/Microsoft.PowerShell.Core/About/about_Throw.md b/reference/5.1/Microsoft.PowerShell.Core/About/about_Throw.md index d4d32399004e..1d4f9c9a6bb3 100644 --- a/reference/5.1/Microsoft.PowerShell.Core/About/about_Throw.md +++ b/reference/5.1/Microsoft.PowerShell.Core/About/about_Throw.md @@ -1,7 +1,7 @@ --- -description: Describes the `throw` keyword, which generates a terminating error. +description: Describes the `throw` keyword, which generates a script-terminating error by default. Locale: en-US -ms.date: 01/18/2026 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_throw?view=powershell-5.1&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Throw @@ -10,12 +10,30 @@ title: about_Throw ## Short description -Describes the `throw` keyword that generates a terminating error. +Describes the `throw` keyword, which generates a script-terminating error by +default. ## Long description -The `throw` keyword causes a terminating error. You can use the `throw` keyword -to stop the processing of a command, function, or script. +The `throw` keyword causes a script-terminating error by default. You can use +the `throw` keyword to stop the processing of a command, function, or script. + +Unlike statement-terminating errors, the `throw` keyword unwinds the entire +call stack. Execution stops completely unless the error is caught by a +`try/catch` block or `trap` statement. + +> [!NOTE] +> `$ErrorActionPreference` can suppress `throw`. When set to `SilentlyContinue` +> or `Ignore`, the error doesn't propagate and execution continues at the next +> statement. When calling an advanced function with +> `-ErrorAction SilentlyContinue`, the parameter translates to a scope-local +> `$ErrorActionPreference` value, so it also suppresses `throw` inside that +> function. Even when suppressed, `throw` still records an entry in `$Error`. +> The `Ignore` value only prevents `$Error` recording for non-terminating +> errors like those generated by `$PSCmdlet.ThrowTerminatingError()`. + +For more information about error categories and `$ErrorActionPreference` +behavior, see [about_Error_Handling][03]. For example, you can use the `throw` keyword in the statement block of an `if` statement to respond to a condition or in the `catch` block of a @@ -50,7 +68,7 @@ At line:1 char:6 If the `throw` keyword is used in a `catch` block without an expression, it throws the current RuntimeException again. For more information, see -[about_Try_Catch_Finally](about_Try_Catch_Finally.md). +[about_Try_Catch_Finally][07]. ## Throwing a string @@ -133,13 +151,23 @@ object is automatically saved in the `$Error` automatic variable. Unlike past versions of PowerShell, don't use the `throw` keyword for parameter validation. See -[about_Functions_Advanced_Parameters](about_Functions_Advanced_Parameters.md) +[about_Functions_Advanced_Parameters][04] for the correct way. ## See also -- [about_Break](about_Break.md) -- [about_Continue](about_Continue.md) -- [about_Scopes](about_Scopes.md) -- [about_Trap](about_Trap.md) -- [about_Try_Catch_Finally](about_Try_Catch_Finally.md) +- [about_Break][01] +- [about_Continue][02] +- [about_Error_Handling][03] +- [about_Scopes][05] +- [about_Trap][06] +- [about_Try_Catch_Finally][07] + + +[01]: about_Break.md +[02]: about_Continue.md +[03]: about_Error_Handling.md +[04]: about_Functions_Advanced_Parameters.md +[05]: about_Scopes.md +[06]: about_Trap.md +[07]: about_Try_Catch_Finally.md diff --git a/reference/5.1/Microsoft.PowerShell.Core/About/about_Trap.md b/reference/5.1/Microsoft.PowerShell.Core/About/about_Trap.md index f560fc5b38a7..d5f4a0e459b9 100644 --- a/reference/5.1/Microsoft.PowerShell.Core/About/about_Trap.md +++ b/reference/5.1/Microsoft.PowerShell.Core/About/about_Trap.md @@ -1,7 +1,7 @@ --- -description: Describes a keyword that handles a terminating error. +description: Describes a keyword that handles statement-terminating and script-terminating errors. Locale: en-US -ms.date: 01/13/2026 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_trap?view=powershell-5.1&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Trap @@ -10,14 +10,16 @@ title: about_Trap ## Short description -Describes a keyword that handles a terminating error. +Describes a keyword that handles statement-terminating and script-terminating +errors. ## Long description -A terminating error stops a statement from running. If PowerShell doesn't -handle a terminating error in some way, PowerShell also stops running the -function or script in the current pipeline. In other languages, such as C#, -terminating errors are known as exceptions. +A terminating error stops a statement from running. PowerShell distinguishes +_statement-terminating_ errors (which stop only the current statement) from +_script-terminating_ errors (which unwind the entire call stack). The `trap` +keyword can handle both kinds. For more information about error categories, see +[about_Error_Handling][07]. The `trap` keyword specifies a list of statements to run when a terminating error occurs. `trap` statements can handle the terminating errors in the @@ -488,8 +490,18 @@ statement. For more information, see ## See also -- [about_Break](about_Break.md) -- [about_Continue](about_Continue.md) -- [about_Scopes](about_Scopes.md) -- [about_Throw](about_Throw.md) -- [about_Try_Catch_Finally](about_Try_Catch_Finally.md) +- [about_Break][01] +- [about_Continue][02] +- [about_Error_Handling][07] +- [about_Scopes][03] +- [about_Throw][04] +- [about_Try_Catch_Finally][05] + + +[01]: about_Break.md +[02]: about_Continue.md +[03]: about_Scopes.md +[04]: about_Throw.md +[05]: about_Try_Catch_Finally.md +[06]: https://wikipedia.org/wiki/JavaScript_syntax#hoisting +[07]: about_Error_Handling.md diff --git a/reference/5.1/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md b/reference/5.1/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md index 95009158ef97..168d73a7601e 100644 --- a/reference/5.1/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md +++ b/reference/5.1/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md @@ -1,7 +1,7 @@ --- -description: Describes how to use the `try`, `catch`, and `finally` blocks to handle terminating errors. +description: Describes how to use the `try`, `catch`, and `finally` blocks to handle statement-terminating and script-terminating errors. Locale: en-US -ms.date: 01/13/2026 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_try_catch_finally?view=powershell-5.1&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Try_Catch_Finally @@ -11,18 +11,31 @@ title: about_Try_Catch_Finally ## Short description Describes how to use the `try`, `catch`, and `finally` blocks to handle -terminating errors. +statement-terminating and script-terminating errors. ## Long description Use `try`, `catch`, and `finally` blocks to respond to or handle terminating -errors in scripts. The `trap` statement can also be used to handle terminating -errors in scripts. For more information, see [about_Trap][05]. +errors in scripts. PowerShell has two kinds of terminating errors: -A terminating error stops a statement from running. If PowerShell does not -handle a terminating error in some way, PowerShell also stops running the -function or script using the current pipeline. In other languages, such as C\#, -terminating errors are referred to as exceptions. +- _statement-terminating_ errors that stop the current statement and +- _script-terminating_ errors that unwind the entire call stack + +Both kinds are caught by `try/catch`. You can also use the `trap` statement to +handle terminating errors. For more information, see [about_Trap][05]. For a +comprehensive overview of all error types, see [about_Error_Handling][06]. + +A statement-terminating error stops the current statement from running, but +PowerShell continues at the next statement unless the error is also +script-terminating. A script-terminating error (such as an error produced by +the `throw` keyword) stops the entire script unless caught by a `try/catch` +block or `trap` statement. + +> [!NOTE] +> `$ErrorActionPreference` can suppress `throw`. When set to `SilentlyContinue` +> or `Ignore`, the error doesn't propagate and execution continues at the next +> statement. For details, see the _Script-terminating errors_ section of +> [about_Error_Handling][07]. Use the `try` block to define a section of a script in which you want PowerShell to monitor for errors. When an error occurs within the `try` block, @@ -255,7 +268,7 @@ try { "An error occurred that could not be resolved." } finally { $wc.Dispose() - if (Test-Path $tempPath) { Remove-Item $tempFile } + if (Test-Path $tempFile) { Remove-Item $tempFile } } ``` @@ -263,6 +276,7 @@ try { - [about_Break][01] - [about_Continue][02] +- [about_Error_Handling][06] - [about_Scopes][03] - [about_Throw][04] - [about_Trap][05] @@ -273,3 +287,5 @@ try { [03]: about_Scopes.md [04]: about_Throw.md [05]: about_Trap.md +[06]: about_Error_Handling.md +[07]: about_Error_Handling.md#script-terminating-errors diff --git a/reference/7.4/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md b/reference/7.4/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md index 55b127c6ff49..4e1ee08bf075 100644 --- a/reference/7.4/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md +++ b/reference/7.4/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md @@ -1,7 +1,7 @@ --- description: Describes variables that store state information for PowerShell. These variables are created and maintained by PowerShell. Locale: en-US -ms.date: 02/10/2026 +ms.date: 04/02/2026 no-loc: [Reset, Current, Background, Blink, Bold, Foreground, Formatting, Hidden, Italic, Reset, Reverse, Underline, PSEventArgs, PSEventSubscriber, PSEdition] online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_automatic_variables?view=powershell-5.1&WT.mc_id=ps-gethelp schema: 2.0.0 @@ -167,8 +167,8 @@ Contains a list of names of the experimental features that are enabled. Contains an array of error objects that represent the most recent errors. The most recent error is the first error object in the array `$Error[0]`. -To prevent an error from being added to the `$Error` array, use the -**ErrorAction** common parameter with a value of **Ignore**. For more +To prevent a non-terminating error from being added to the `$Error` array, use +the **ErrorAction** common parameter with a value of **Ignore**. For more information, see [about_CommonParameters][53]. ### `$Event` diff --git a/reference/7.4/Microsoft.PowerShell.Core/About/about_CommonParameters.md b/reference/7.4/Microsoft.PowerShell.Core/About/about_CommonParameters.md index fa55178e6cdf..5893ac23cf3c 100644 --- a/reference/7.4/Microsoft.PowerShell.Core/About/about_CommonParameters.md +++ b/reference/7.4/Microsoft.PowerShell.Core/About/about_CommonParameters.md @@ -1,7 +1,7 @@ --- description: Describes the parameters that can be used with any cmdlet. Locale: en-US -ms.date: 01/18/2026 +ms.date: 04/02/2026 no-loc: [Confirm, Debug, ErrorAction, ErrorVariable, InformationAction, InformationVariable, OutBuffer, OutVariable, PipelineVariable, ProgressAction, Verbose, WarningAction, WarningVariable, WhatIf] online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-5.1&WT.mc_id=ps-gethelp schema: 2.0.0 @@ -105,8 +105,8 @@ the display of debugging messages when `$DebugPreference` isn't ### -ErrorAction Determines how the cmdlet responds to a non-terminating error from the command. -This parameter works only when the command generates a non-terminating error, -such as those from the `Write-Error` cmdlet. +This parameter overrides the value of the `$ErrorActionPreference` variable for +non-terminating errors generated by the command or the `Write-Error` cmdlet. ```yaml Type: ActionPreference @@ -124,22 +124,28 @@ variable for the current command. Because the default value of the `$ErrorActionPreference` variable is `Continue`, error messages are displayed and execution continues unless you use the `ErrorAction` parameter. -The `ErrorAction` parameter has no effect on terminating errors (such as -missing data, parameters that aren't valid, or insufficient permissions) that -prevent a command from completing successfully. +The `-ErrorAction` parameter doesn't prevent statement-terminating errors +(such as missing data, parameters that aren't valid, or insufficient +permissions) from stopping the current statement. However, when set to `Stop`, +it escalates non-terminating errors to script-terminating errors, making them +catchable by `try/catch`. For more information about error categories, see +[about_Error_Handling][15]. - `Break` Enters the debugger when an error occurs or an exception is raised. - `Continue` displays the error message and continues executing the command. `Continue` is the default. - `Ignore` suppresses the error message and continues executing the command. - Unlike `SilentlyContinue`, `Ignore` doesn't add the error message to the - `$Error` automatic variable. The `Ignore` value is introduced in PowerShell - 3.0. + Unlike `SilentlyContinue`, `Ignore` doesn't add the non-terminating error to + the `$Error` automatic variable. The `Ignore` value is introduced in + PowerShell 3.0. - `Inquire` displays the error message and prompts you for confirmation before continuing execution. This value is rarely used. - `SilentlyContinue` suppresses the error message and continues executing the command. -- `Stop` displays the error message and stops executing the command. +- `Stop` displays the error message and stops executing the command. The + `Stop` value escalates the non-terminating error to a terminating error + by generating an `ActionPreferenceStopException`. The error can then + be caught by a `try/catch` block or `trap` statement. - `Suspend` is only available for workflows which aren't supported in PowerShell 6 and beyond. diff --git a/reference/7.4/Microsoft.PowerShell.Core/About/about_Error_Handling.md b/reference/7.4/Microsoft.PowerShell.Core/About/about_Error_Handling.md new file mode 100644 index 000000000000..a6b16ff5567c --- /dev/null +++ b/reference/7.4/Microsoft.PowerShell.Core/About/about_Error_Handling.md @@ -0,0 +1,562 @@ +--- +description: Describes the types of errors in PowerShell and the mechanisms for handling them. +Locale: en-US +ms.date: 03/26/2026 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_error_handling?view=powershell-7.4&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Error_Handling +--- +# about_Error_Handling + +## Short description + +Describes the types of errors in PowerShell and the mechanisms for handling +them. + +## Long description + +PowerShell distinguishes three categories of errors: + +- Non-terminating errors +- Statement-terminating errors +- Script-terminating errors + +Understanding the distinction is essential for writing reliable scripts and +modules, because each category has different default behavior and requires +different handling techniques. + +Additionally, external (native) programs report failure through exit codes, +which PowerShell tracks separately from its own error system. + +## Types of errors + +### Non-terminating errors + +A non-terminating error reports a problem but doesn't stop the pipeline. The +command continues processing subsequent input objects. Non-terminating errors +are generated by: + +- The `Write-Error` cmdlet +- The `$PSCmdlet.WriteError()` method in advanced functions +- Cmdlets that encounter recoverable failures on individual input objects + +By default, PowerShell displays the error message and continues execution. + +```powershell +# Non-terminating error: the pipeline continues after the failure +'file1.txt', 'noSuchFile.txt', 'file3.txt' | ForEach-Object { + Get-Content $_ -ErrorAction Continue +} +``` + +In this example, `Get-Content` reports a non-terminating error for +`noSuchFile.txt` and then continues processing `file3.txt`. + +Non-terminating errors do **not** trigger `catch` or `trap` by default. + +### Statement-terminating errors + +A statement-terminating error stops the current statement (pipeline) from +running, but execution continues at the next statement in the script. +Statement-terminating errors are generated by: + +- The `$PSCmdlet.ThrowTerminatingError()` method in advanced functions and + compiled cmdlets +- Engine errors such as `CommandNotFoundException` (calling a command that + doesn't exist) and `ParameterBindingException` (invalid parameter arguments) +- .NET method calls that throw exceptions, such as `[int]::Parse('abc')` + +```powershell +# Statement-terminating error: Get-Item fails, but the next statement runs +Get-Item -Path 'C:\NoSuchFile.txt' +Write-Output 'This still runs' +``` + +Statement-terminating errors can be caught by `try/catch` and `trap`. + +> [!NOTE] +> `.ThrowTerminatingError()` doesn't consult the `-ErrorAction` parameter +> (except for the `Break` value, which enters the debugger). However, +> `$ErrorActionPreference` _does_ apply to statement-terminating errors +> through the engine's statement-level handler. For example, +> `$ErrorActionPreference = 'SilentlyContinue'` can suppress a +> statement-terminating error so that the script continues at the next +> statement. The `-ErrorAction` parameter can't do this. For details, see +> [The $ErrorActionPreference asymmetry][05]. + +### Script-terminating errors + +A script-terminating error unwinds the entire call stack. Execution stops +completely unless the error is caught by a `try/catch` block or `trap` +statement. Script-terminating errors are generated by: + +- The `throw` keyword +- Parse errors (syntax errors that prevent the script from being compiled) +- Non-terminating errors **escalated** by `-ErrorAction Stop` or + `$ErrorActionPreference = 'Stop'` in non-advanced contexts. For more + information, see [How escalation works][01]. +- Certain critical engine failures + +```powershell +# 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)' +``` + +The `throw` keyword generates a script-terminating error by default. However, +`$ErrorActionPreference` _can_ suppress `throw` when set to `SilentlyContinue` +or `Ignore`. When calling an advanced function with +`-ErrorAction SilentlyContinue`, the parameter translates to a scope-local +`$ErrorActionPreference` value, so it also suppresses `throw` inside that +function. + +> [!NOTE] +> Even with `$ErrorActionPreference = 'Ignore'`, a `throw` that's suppressed +> still records an entry in `$Error`. The `Ignore` value only prevents `$Error` +> recording for **non-terminating** errors. + +> [!IMPORTANT] +> The terms _statement-terminating_ and _script-terminating_ describe the scope +> of impact, not the severity of the error. A statement-terminating error stops +> one statement. A script-terminating error stops the entire script and its +> callers. Both can be caught by `try/catch`. + +### External program errors + +External (native) programs don't participate in PowerShell's error system +directly. They report failure through a non-zero exit code, which PowerShell +stores in the `$LASTEXITCODE` automatic variable. + +```powershell +git clone https://example.com/nonexistent.git 2>$null +if ($LASTEXITCODE -ne 0) { + Write-Error "git failed with exit code $LASTEXITCODE" +} +``` + +By default, a non-zero exit code from a native program: + +- Sets `$?` to `$false` +- Does **not** generate an `ErrorRecord` in `$Error` +- Does **not** trigger `catch` or `trap` + +PowerShell 7.3 added the experimental preference variable +`$PSNativeCommandUseErrorActionPreference`, which became a stable feature in +7.4. When you set this variable to `$true`, it causes a non-zero exit code to +emit a **non-terminating error** whose message states the specific exit code (a +`NativeCommandExitException`). This error respects `$ErrorActionPreference`, so +setting it to `Stop` promotes the error to a script-terminating error that can +be caught with `try`/`catch`. + +## Error state variables + +PowerShell maintains several automatic variables that reflect the current error +state. + +### `$?` + +Contains `$true` if the last operation succeeded and `$false` if it produced +any error (non-terminating or terminating). For native commands, `$?` is set +based on the exit code: `$true` for exit code `0`, `$false` otherwise. + +```powershell +Get-Item -Path 'C:\NoSuchFile.txt' 2>$null +$? # False +``` + +### `$Error` + +An `ArrayList` that stores the most recent error records, with the most recent +error at index `0`. The list holds up to `$MaximumErrorCount` entries (default +256). + +All terminating errors are added to `$Error`. For terminating errors, `Ignore` +suppresses display but still records the error in `$Error`. All non-terminating +are added to `$Error` unless `-ErrorAction Ignore` is used on non-terminating +errors, which prevents both display and recording. + +### `$LASTEXITCODE` + +Contains the exit code of the last native program that ran. A value of `0` +conventionally indicates success. Any non-zero value indicates failure. This +variable isn't affected by PowerShell cmdlet errors. + +## Control error behavior + +### The `-ErrorAction` common parameter + +The `-ErrorAction` common parameter overrides `$ErrorActionPreference` for a +single command. It controls how PowerShell responds to **non-terminating** +errors from that command. + +| Value | Behavior | +| ------------------ | -------------------------------------------------------------------- | +| `Continue` | Display the error and continue (default) | +| `SilentlyContinue` | Suppress display, add to `$Error`, continue | +| `Ignore` | Suppress display and don't add to `$Error` | +| `Stop` | **Escalate** to a terminating error (see [How escalation works][01]) | +| `Inquire` | Prompt the user for a decision | +| `Break` | Enter the debugger | + +`-ErrorAction` doesn't change the behavior of errors generated by +`$PSCmdlet.ThrowTerminatingError()`. Those errors are always +statement-terminating regardless of the caller's preference. + +### The `$ErrorActionPreference `variable + +The `$ErrorActionPreference` preference variable applies to all commands in the +current scope and child scopes. It accepts the same values as `-ErrorAction`. + +```powershell +$ErrorActionPreference = 'Stop' +# All non-terminating errors in this scope now become terminating +Write-Error 'This now throws' # Generates ActionPreferenceStopException +``` + +When `-ErrorAction` is specified on a command, it takes precedence over +`$ErrorActionPreference` for that command. + +### How escalation works + +When `-ErrorAction Stop` or `$ErrorActionPreference = 'Stop'` is in effect, +PowerShell converts non-terminating errors into terminating errors using the +following mechanism: + +1. A cmdlet calls `WriteError()` internally to emit a non-terminating error. +1. The engine checks the effective `ErrorAction` preference for the command. +1. Because the preference is `Stop`, the engine creates an + `ActionPreferenceStopException` that wraps the original error record. +1. If caught by `catch`, the original error information is accessible through + `$_.Exception.ErrorRecord`. + +The scope of the escalated error depends on context: + +- In **non-advanced** scripts, functions, or script blocks, setting + `$ErrorActionPreference = 'Stop'` escalates to a **script-terminating** + error. The error propagates up the call stack. +- In **advanced** functions and script blocks (those with `[CmdletBinding()]`), + the error remains **statement-terminating**. Execution continues at the next + statement after the call. +- Passing `-ErrorAction Stop` to an advanced function has the same effect as + setting `$ErrorActionPreference = 'Stop'` inside it, because `-ErrorAction` + translates to a scope-local `$ErrorActionPreference` value. + +### Escalation examples + +- NON-advanced: script-terminating ('after' does NOT print) + + ```powershell + & { + param() + $ErrorActionPreference = 'Stop' + Get-Item 'NoSuchPath' + } 2>$null + 'after' + ``` + +- ADVANCED: statement-terminating ('after' DOES print) + + ```powershell + & { + [CmdletBinding()] + param() + $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' + } 2>$null + 'after' + ``` + +- Without `-ErrorAction Stop`: non-terminating, catch doesn't run + + ```powershell + try { + Write-Error 'This is non-terminating' + Write-Output 'Execution continues' + } catch { + Write-Output "Caught: $_" # Not reached + } + ``` + +- With `-ErrorAction Stop`: escalated to terminating + + ```powershell + try { + Write-Error 'This becomes terminating' -ErrorAction Stop + } catch { + Write-Output "Caught: $_" # Reached + } + ``` + +Escalated errors can be caught by their original exception type. The engine +unwraps the `ActionPreferenceStopException` to find the underlying exception: + +```powershell +try { + Get-Item -Path 'C:\NoSuchFile.txt' -ErrorAction Stop +} catch [System.Management.Automation.ItemNotFoundException] { + Write-Output "File not found: $($_.Exception.Message)" +} +``` + +### The `$ErrorActionPreference` asymmetry + +The `-ErrorAction` parameter and the `$ErrorActionPreference` variable behave +differently with terminating errors. It's important to understand this +asymmetry: + +- `-ErrorAction` only affects **non-terminating** errors. When a cmdlet calls + `$PSCmdlet.ThrowTerminatingError()`, the `-ErrorAction` parameter is ignored + (except for `Break`, which enters the debugger). The error is always thrown. + +- `$ErrorActionPreference` affects **both** non-terminating and + statement-terminating errors. The engine's statement-level error handler + reads `$ErrorActionPreference` (not the `-ErrorAction` parameter) and can + suppress a statement-terminating error when the value is `SilentlyContinue` + or `Ignore`. + +```powershell +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' +``` + +> [!IMPORTANT] +> `$ErrorActionPreference` can't suppress errors that have +> `SuppressPromptInInterpreter` set to `true`. These always propagate +> regardless of the preference variable. Examples of this type of error +> include: +> +> - `ActionPreferenceStopException` from `-ErrorAction Stop` escalation +> - Errors inside PowerShell class methods +> - `PipelineStoppedException` + +## Handle errors + +### `try/catch/finally` + +Use `try/catch/finally` to handle statement-terminating and script-terminating +errors. When an error occurs inside a `try` block, PowerShell searches for a +matching `catch` block. The `finally` block always runs, whether or not an +error occurred. + +```powershell +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 +} +``` + +Inside a `try` block, the engine sets an internal flag that causes non- +terminating errors escalated by `-ErrorAction Stop` or +`$ErrorActionPreference = 'Stop'` to propagate to the `catch` block. This +is designed behavior, not a special case. + +For full syntax details, see [about_Try_Catch_Finally][12]. + +### `trap` + +The `trap` statement handles terminating errors at the scope level. When an +error occurs anywhere in the enclosing scope, the `trap` block runs. + +- **Default** (no `break` or `continue`): The error is displayed and execution + continues at the next statement after the one that caused the error. +- **`continue`** in the trap: Suppresses the error message and resumes at the + next statement. +- **`break`** in the trap: The error propagates to the parent scope. + +```powershell +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' +``` + +For full syntax details, see [about_Trap][11]. + +## Reporting errors in functions and scripts + +When writing functions and scripts, choose the error-reporting mechanism that +matches the severity of the failure. + +### Non-terminating - use `Write-Error` + +Use `Write-Error` when the function can continue processing other input. This +is appropriate for pipeline functions that process multiple objects and +encounter failures on individual items. + +```powershell +function Test-Path-Safe { + [CmdletBinding()] + param([Parameter(ValueFromPipeline)][string]$Path) + process { + if (-not (Test-Path $Path)) { + Write-Error "Path not found: $Path" + return + } + $Path + } +} +``` + +> [!NOTE] +> In advanced functions (those with `[CmdletBinding()]`), use +> `$PSCmdlet.WriteError()` instead of `Write-Error` to ensure that `$?` is +> properly set to `$false` in the caller's scope. The `Write-Error` cmdlet +> doesn't always set `$?` correctly. + +### Statement-terminating - use `$PSCmdlet.ThrowTerminatingError()` + +Use `$PSCmdlet.ThrowTerminatingError()` when the function can't continue at all +but the caller should decide how to handle the failure. This is the recommended +approach in advanced functions. + +```powershell +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 +} +``` + +After the error leaves the function, the caller treats it as a non-terminating +error by default. The caller can escalate it with `-ErrorAction Stop`. + +### Script-terminating - use `throw` + +Use `throw` when recovery isn't possible and the entire script should stop. + +```powershell +$config = Get-Content 'config.json' -ErrorAction SilentlyContinue | + ConvertFrom-Json + +if (-not $config) { + throw 'Cannot proceed without a valid configuration file.' +} +``` + +### Which mechanism to use + +- When processing multiple inputs where some may fail, use `Write-Error` or + `$PSCmdlet.WriteError()`. +- If the function can't continue, use `$PSCmdlet.ThrowTerminatingError()` and + let the caller decide how to handle it. +- If the entire script must stop immediately, use `throw`. + +## Summary of error types + +The following tables summarize the properties and behaviors of the different +error types in PowerShell. + +### Non-terminating error + +[Non-terminating errors][02] can be generated by `Write-Error` or +`$PSCmdlet.WriteError()`. + +| Attribute | Description | +| ------------------------------------ | ------------------------------- | +| Scope of impact | Pipeline continues | +| Caught by `catch` | No (unless escalated) | +| Caught by `trap` | No (unless escalated) | +| Added to `$Error` | Yes (unless `Ignore`) | +| Sets `$?` to `$false` | Yes | +| Affected by `-ErrorAction` | Yes | +| Affected by `$ErrorActionPreference` | Yes | + +### Statement-terminating error + +[Statement-terminating errors][04] can be generated by +`ThrowTerminatingError()`, engine errors, .NET method exceptions, or +`-ErrorAction Stop` in advanced contexts. + +| Attribute | Description | +| ------------------------------------ | ----------------------------------------- | +| Scope of impact | Current statement stops; script continues | +| Caught by `catch` | Yes | +| Caught by `trap` | Yes | +| Added to `$Error` | Yes | +| Sets `$?` to `$false` | Yes | +| Affected by `-ErrorAction` | No (`Break` only) | +| Affected by `$ErrorActionPreference` | Yes (can suppress) | + +### Script-terminating error + +[Script-terminating errors][03] can be generated by `throw`, parse errors, or +`-ErrorAction Stop` in non-advanced contexts. + +| Attribute | Description | +| ------------------------------------ | ----------------------------- | +| Scope of impact | Call stack unwinds | +| Caught by `catch` | Yes | +| Caught by `trap` | Yes | +| Added to `$Error` | Yes | +| Sets `$?` to `$false` | Yes | +| Affected by `-ErrorAction` | No | +| Affected by `$ErrorActionPreference` | `throw`: Yes (can suppress) | +| Affected by `$ErrorActionPreference` | Escalated: depends on context | + +## See also + +- [about_Automatic_Variables][06] +- [about_CommonParameters][07] +- [about_Preference_Variables][09] +- [about_Output_Streams][08] +- [about_Throw][10] +- [about_Trap][11] +- [about_Try_Catch_Finally][12] + + +[01]: #how-escalation-works +[02]: #non-terminating-errors +[03]: #script-terminating-errors +[04]: #statement-terminating-errors +[05]: #the-erroractionpreference-asymmetry +[06]: about_Automatic_Variables.md +[07]: about_CommonParameters.md +[08]: about_Output_Streams.md +[09]: about_Preference_Variables.md +[10]: about_Throw.md +[11]: about_Trap.md +[12]: about_Try_Catch_Finally.md diff --git a/reference/7.4/Microsoft.PowerShell.Core/About/about_Preference_Variables.md b/reference/7.4/Microsoft.PowerShell.Core/About/about_Preference_Variables.md index 45e84f87bc0a..686bf06c1803 100644 --- a/reference/7.4/Microsoft.PowerShell.Core/About/about_Preference_Variables.md +++ b/reference/7.4/Microsoft.PowerShell.Core/About/about_Preference_Variables.md @@ -1,7 +1,7 @@ --- description: Variables that customize the behavior of PowerShell. Locale: en-US -ms.date: 12/01/2025 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7.4&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Preference_Variables @@ -388,25 +388,32 @@ The valid values are as follows: raised. - **Continue**: (Default) Displays the error message and continues executing. - **Ignore**: Suppresses the error message and continues to execute the - command. The **Ignore** value is intended for per-command use, not for use as - saved preference. **Ignore** isn't a valid value for the - `$ErrorActionPreference` variable. + command. Unlike **SilentlyContinue**, **Ignore** doesn't add the error + message to the `$Error` automatic variable. The **Ignore** value is also + valid for `$ErrorActionPreference`, where it suppresses both non-terminating + and statement-terminating errors. However, **Ignore** only prevents `$Error` + recording for non-terminating errors. Terminating errors that are suppressed + by `Ignore` are still recorded in `$Error`. - **Inquire**: Displays the error message and asks you whether you want to continue. - **SilentlyContinue**: No effect. The error message isn't displayed and execution continues without interruption. - **Stop**: Displays the error message and stops executing. In addition to the - error generated, the **Stop** value generates an ActionPreferenceStopException - object to the error stream. + error generated, the **Stop** value generates an + ActionPreferenceStopException object to the error stream. - **Suspend**: Automatically suspends a workflow job to allow for further investigation. After investigation, the workflow can be resumed. The **Suspend** value is intended for per-command use, not for use as saved preference. **Suspend** isn't a valid value for the `$ErrorActionPreference` variable. -`$ErrorActionPreference` and the **ErrorAction** parameter don't affect how -PowerShell responds to terminating errors that stop cmdlet processing. For more -information about the **ErrorAction** common parameter, see +`$ErrorActionPreference` applies to **both** non-terminating and +statement-terminating errors. Unlike the `-ErrorAction` parameter (which only +affects non-terminating errors), the preference variable can also suppress or +escalate errors generated by `$PSCmdlet.ThrowTerminatingError()`. When set to +**Stop**, it escalates non-terminating errors to script-terminating errors. For +more information about error categories, see [about_Error_Handling][67]. For +more information about the **ErrorAction** common parameter, see [about_CommonParameters][29]. Many native commands write to `stderr` as an alternative stream for additional @@ -419,10 +426,9 @@ like when using redirection operators (`2>&1`), aren't written to the `$Error` variable and the preference variable `$ErrorActionPreference` doesn't affect the redirected output. -PowerShell 7.3 added an experimental feature that allows you to control how -messages written to `stderr` are handled. - -For more information see, [$PSNativeCommandUseErrorActionPreference][18]. +PowerShell 7.4 added a feature that allows you to control how messages written +to `stderr` are handled. For more information, see +[$PSNativeCommandUseErrorActionPreference][18]. ### Examples @@ -1692,6 +1698,7 @@ At line:1 char:1 - [about_Automatic_Variables][28] - [about_CommonParameters][29] - [about_Environment_Variables][30] +- [about_Error_Handling][67] - [about_Profiles][36] - [about_Remote][39] - [about_Scopes][40] @@ -1763,3 +1770,4 @@ At line:1 char:1 [64]: xref:System.Text.UTF7Encoding [65]: xref:System.Text.UTF8Encoding [66]: about_Functions_CmdletBindingAttribute.md +[67]: about_Error_Handling.md diff --git a/reference/7.4/Microsoft.PowerShell.Core/About/about_Throw.md b/reference/7.4/Microsoft.PowerShell.Core/About/about_Throw.md index 5f4d366f72f8..3a0b72adb5a6 100644 --- a/reference/7.4/Microsoft.PowerShell.Core/About/about_Throw.md +++ b/reference/7.4/Microsoft.PowerShell.Core/About/about_Throw.md @@ -1,7 +1,7 @@ --- -description: Describes the `throw` keyword, which generates a terminating error. +description: Describes the `throw` keyword, which generates a script-terminating error by default. Locale: en-US -ms.date: 01/18/2026 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_throw?view=powershell-7.4&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Throw @@ -10,12 +10,30 @@ title: about_Throw ## Short description -Describes the `throw` keyword that generates a terminating error. +Describes the `throw` keyword, which generates a script-terminating error by +default. ## Long description -The `throw` keyword causes a terminating error. You can use the `throw` keyword -to stop the processing of a command, function, or script. +The `throw` keyword causes a script-terminating error by default. You can use +the `throw` keyword to stop the processing of a command, function, or script. + +Unlike statement-terminating errors, the `throw` keyword unwinds the entire +call stack. Execution stops completely unless the error is caught by a +`try/catch` block or `trap` statement. + +> [!NOTE] +> `$ErrorActionPreference` can suppress `throw`. When set to `SilentlyContinue` +> or `Ignore`, the error doesn't propagate and execution continues at the next +> statement. When calling an advanced function with +> `-ErrorAction SilentlyContinue`, the parameter translates to a scope-local +> `$ErrorActionPreference` value, so it also suppresses `throw` inside that +> function. Even when suppressed, `throw` still records an entry in `$Error`. +> The `Ignore` value only prevents `$Error` recording for non-terminating +> errors like those generated by `$PSCmdlet.ThrowTerminatingError()`. + +For more information about error categories and `$ErrorActionPreference` +behavior, see [about_Error_Handling][03]. For example, you can use the `throw` keyword in the statement block of an `if` statement to respond to a condition or in the `catch` block of a @@ -46,7 +64,7 @@ Exception: ScriptHalted If the `throw` keyword is used in a `catch` block without an expression, it throws the current RuntimeException again. For more information, see -[about_Try_Catch_Finally](about_Try_Catch_Finally.md). +[about_Try_Catch_Finally][07]. ## Throwing a string @@ -116,13 +134,23 @@ object is automatically saved in the `$Error` automatic variable. Unlike past versions of PowerShell, don't use the `throw` keyword for parameter validation. See -[about_Functions_Advanced_Parameters](about_Functions_Advanced_Parameters.md) +[about_Functions_Advanced_Parameters][04] for the correct way. ## See also -- [about_Break](about_Break.md) -- [about_Continue](about_Continue.md) -- [about_Scopes](about_Scopes.md) -- [about_Trap](about_Trap.md) -- [about_Try_Catch_Finally](about_Try_Catch_Finally.md) +- [about_Break][01] +- [about_Continue][02] +- [about_Error_Handling][03] +- [about_Scopes][05] +- [about_Trap][06] +- [about_Try_Catch_Finally][07] + + +[01]: about_Break.md +[02]: about_Continue.md +[03]: about_Error_Handling.md +[04]: about_Functions_Advanced_Parameters.md +[05]: about_Scopes.md +[06]: about_Trap.md +[07]: about_Try_Catch_Finally.md diff --git a/reference/7.4/Microsoft.PowerShell.Core/About/about_Trap.md b/reference/7.4/Microsoft.PowerShell.Core/About/about_Trap.md index 3867f3b5e570..8ca161ec153c 100644 --- a/reference/7.4/Microsoft.PowerShell.Core/About/about_Trap.md +++ b/reference/7.4/Microsoft.PowerShell.Core/About/about_Trap.md @@ -1,7 +1,7 @@ --- -description: Describes a keyword that handles a terminating error. +description: Describes a keyword that handles statement-terminating and script-terminating errors. Locale: en-US -ms.date: 01/13/2026 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_trap?view=powershell-7.4&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Trap @@ -10,14 +10,16 @@ title: about_Trap ## Short description -Describes a keyword that handles a terminating error. +Describes a keyword that handles statement-terminating and script-terminating +errors. ## Long description -A terminating error stops a statement from running. If PowerShell doesn't -handle a terminating error in some way, PowerShell also stops running the -function or script in the current pipeline. In other languages, such as C#, -terminating errors are known as exceptions. +A terminating error stops a statement from running. PowerShell distinguishes +_statement-terminating_ errors (which stop only the current statement) from +_script-terminating_ errors (which unwind the entire call stack). The `trap` +keyword can handle both kinds. For more information about error categories, see +[about_Error_Handling][07]. The `trap` keyword specifies a list of statements to run when a terminating error occurs. `trap` statements can handle the terminating errors in the @@ -286,7 +288,7 @@ after loop In the output, you can see the loops continue until the last iteration. When the script tries to divide 1 by 0, PowerShell throws a terminating error. The -script skips the rest of the `foreach` statement, runs the `try` statement, +script skips the rest of the `foreach` statement, runs the `trap` statement, and continues after the `foreach` statement. ## Trapping errors and scope @@ -468,6 +470,7 @@ statement. For more information, see - [about_Break][01] - [about_Continue][02] +- [about_Error_Handling][07] - [about_Scopes][03] - [about_Throw][04] - [about_Try_Catch_Finally][05] @@ -479,3 +482,4 @@ statement. For more information, see [04]: about_Throw.md [05]: about_Try_Catch_Finally.md [06]: https://wikipedia.org/wiki/JavaScript_syntax#hoisting +[07]: about_Error_Handling.md diff --git a/reference/7.4/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md b/reference/7.4/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md index 991e4460fb9e..046510b62ac9 100644 --- a/reference/7.4/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md +++ b/reference/7.4/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md @@ -1,7 +1,7 @@ --- -description: Describes how to use the `try`, `catch`, and `finally` blocks to handle terminating errors. +description: Describes how to use the `try`, `catch`, and `finally` blocks to handle statement-terminating and script-terminating errors. Locale: en-US -ms.date: 01/13/2026 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_try_catch_finally?view=powershell-7.4&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Try_Catch_Finally @@ -11,18 +11,31 @@ title: about_Try_Catch_Finally ## Short description Describes how to use the `try`, `catch`, and `finally` blocks to handle -terminating errors. +statement-terminating and script-terminating errors. ## Long description Use `try`, `catch`, and `finally` blocks to respond to or handle terminating -errors in scripts. The `trap` statement can also be used to handle terminating -errors in scripts. For more information, see [about_Trap][05]. +errors in scripts. PowerShell has two kinds of terminating errors: -A terminating error stops a statement from running. If PowerShell does not -handle a terminating error in some way, PowerShell also stops running the -function or script using the current pipeline. In other languages, such as C\#, -terminating errors are referred to as exceptions. +- _statement-terminating_ errors that stop the current statement and +- _script-terminating_ errors that unwind the entire call stack + +Both kinds are caught by `try/catch`. You can also use the `trap` statement to +handle terminating errors. For more information, see [about_Trap][05]. For a +comprehensive overview of all error types, see [about_Error_Handling][06]. + +A statement-terminating error stops the current statement from running, but +PowerShell continues at the next statement unless the error is also +script-terminating. A script-terminating error (such as an error produced by +the `throw` keyword) stops the entire script unless caught by a `try/catch` +block or `trap` statement. + +> [!NOTE] +> `$ErrorActionPreference` can suppress `throw`. When set to `SilentlyContinue` +> or `Ignore`, the error doesn't propagate and execution continues at the next +> statement. For details, see the _Script-terminating errors_ section of +> [about_Error_Handling][07]. Use the `try` block to define a section of a script in which you want PowerShell to monitor for errors. When an error occurs within the `try` block, @@ -255,7 +268,7 @@ try { "An error occurred that could not be resolved." } finally { $wc.Dispose() - if (Test-Path $tempPath) { Remove-Item $tempFile } + if (Test-Path $tempFile) { Remove-Item $tempFile } } ``` @@ -263,6 +276,7 @@ try { - [about_Break][01] - [about_Continue][02] +- [about_Error_Handling][06] - [about_Scopes][03] - [about_Throw][04] - [about_Trap][05] @@ -273,3 +287,5 @@ try { [03]: about_Scopes.md [04]: about_Throw.md [05]: about_Trap.md +[06]: about_Error_Handling.md +[07]: about_Error_Handling.md#script-terminating-errors diff --git a/reference/7.5/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md b/reference/7.5/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md index 66a95cdeb02c..b13dd0cc2c88 100644 --- a/reference/7.5/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md +++ b/reference/7.5/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md @@ -1,7 +1,7 @@ --- description: Describes variables that store state information for PowerShell. These variables are created and maintained by PowerShell. Locale: en-US -ms.date: 02/10/2026 +ms.date: 04/02/2026 no-loc: [Reset, Current, Background, Blink, Bold, Foreground, Formatting, Hidden, Italic, Reset, Reverse, Underline, PSEventArgs, PSEventSubscriber, PSEdition] online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_automatic_variables?view=powershell-7.5&WT.mc_id=ps-gethelp schema: 2.0.0 @@ -167,8 +167,8 @@ Contains a list of names of the experimental features that are enabled. Contains an array of error objects that represent the most recent errors. The most recent error is the first error object in the array `$Error[0]`. -To prevent an error from being added to the `$Error` array, use the -**ErrorAction** common parameter with a value of **Ignore**. For more +To prevent a non-terminating error from being added to the `$Error` array, use +the **ErrorAction** common parameter with a value of **Ignore**. For more information, see [about_CommonParameters][53]. ### `$Event` diff --git a/reference/7.5/Microsoft.PowerShell.Core/About/about_CommonParameters.md b/reference/7.5/Microsoft.PowerShell.Core/About/about_CommonParameters.md index 06cce87a2945..705c53b5c3d0 100644 --- a/reference/7.5/Microsoft.PowerShell.Core/About/about_CommonParameters.md +++ b/reference/7.5/Microsoft.PowerShell.Core/About/about_CommonParameters.md @@ -1,7 +1,7 @@ --- description: Describes the parameters that can be used with any cmdlet. Locale: en-US -ms.date: 01/18/2026 +ms.date: 04/02/2026 no-loc: [Confirm, Debug, ErrorAction, ErrorVariable, InformationAction, InformationVariable, OutBuffer, OutVariable, PipelineVariable, ProgressAction, Verbose, WarningAction, WarningVariable, WhatIf] online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-7.5&WT.mc_id=ps-gethelp schema: 2.0.0 @@ -105,8 +105,8 @@ the display of debugging messages when `$DebugPreference` isn't ### -ErrorAction Determines how the cmdlet responds to a non-terminating error from the command. -This parameter works only when the command generates a non-terminating error, -such as those from the `Write-Error` cmdlet. +This parameter overrides the value of the `$ErrorActionPreference` variable for +non-terminating errors generated by the command or the `Write-Error` cmdlet. ```yaml Type: ActionPreference @@ -124,22 +124,28 @@ variable for the current command. Because the default value of the `$ErrorActionPreference` variable is `Continue`, error messages are displayed and execution continues unless you use the `ErrorAction` parameter. -The `ErrorAction` parameter has no effect on terminating errors (such as -missing data, parameters that aren't valid, or insufficient permissions) that -prevent a command from completing successfully. +The `-ErrorAction` parameter doesn't prevent statement-terminating errors +(such as missing data, parameters that aren't valid, or insufficient +permissions) from stopping the current statement. However, when set to `Stop`, +it escalates non-terminating errors to script-terminating errors, making them +catchable by `try/catch`. For more information about error categories, see +[about_Error_Handling][15]. - `Break` Enters the debugger when an error occurs or an exception is raised. - `Continue` displays the error message and continues executing the command. `Continue` is the default. - `Ignore` suppresses the error message and continues executing the command. - Unlike `SilentlyContinue`, `Ignore` doesn't add the error message to the - `$Error` automatic variable. The `Ignore` value is introduced in PowerShell - 3.0. + Unlike `SilentlyContinue`, `Ignore` doesn't add the non-terminating error to + the `$Error` automatic variable. The `Ignore` value is introduced in + PowerShell 3.0. - `Inquire` displays the error message and prompts you for confirmation before continuing execution. This value is rarely used. - `SilentlyContinue` suppresses the error message and continues executing the command. -- `Stop` displays the error message and stops executing the command. +- `Stop` displays the error message and stops executing the command. The + `Stop` value escalates the non-terminating error to a terminating error + by generating an `ActionPreferenceStopException`. The error can then + be caught by a `try/catch` block or `trap` statement. - `Suspend` is only available for workflows which aren't supported in PowerShell 6 and beyond. diff --git a/reference/7.5/Microsoft.PowerShell.Core/About/about_Error_Handling.md b/reference/7.5/Microsoft.PowerShell.Core/About/about_Error_Handling.md new file mode 100644 index 000000000000..d39ac3ab850d --- /dev/null +++ b/reference/7.5/Microsoft.PowerShell.Core/About/about_Error_Handling.md @@ -0,0 +1,562 @@ +--- +description: Describes the types of errors in PowerShell and the mechanisms for handling them. +Locale: en-US +ms.date: 03/26/2026 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_error_handling?view=powershell-7.5&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Error_Handling +--- +# about_Error_Handling + +## Short description + +Describes the types of errors in PowerShell and the mechanisms for handling +them. + +## Long description + +PowerShell distinguishes three categories of errors: + +- Non-terminating errors +- Statement-terminating errors +- Script-terminating errors + +Understanding the distinction is essential for writing reliable scripts and +modules, because each category has different default behavior and requires +different handling techniques. + +Additionally, external (native) programs report failure through exit codes, +which PowerShell tracks separately from its own error system. + +## Types of errors + +### Non-terminating errors + +A non-terminating error reports a problem but doesn't stop the pipeline. The +command continues processing subsequent input objects. Non-terminating errors +are generated by: + +- The `Write-Error` cmdlet +- The `$PSCmdlet.WriteError()` method in advanced functions +- Cmdlets that encounter recoverable failures on individual input objects + +By default, PowerShell displays the error message and continues execution. + +```powershell +# Non-terminating error: the pipeline continues after the failure +'file1.txt', 'noSuchFile.txt', 'file3.txt' | ForEach-Object { + Get-Content $_ -ErrorAction Continue +} +``` + +In this example, `Get-Content` reports a non-terminating error for +`noSuchFile.txt` and then continues processing `file3.txt`. + +Non-terminating errors do **not** trigger `catch` or `trap` by default. + +### Statement-terminating errors + +A statement-terminating error stops the current statement (pipeline) from +running, but execution continues at the next statement in the script. +Statement-terminating errors are generated by: + +- The `$PSCmdlet.ThrowTerminatingError()` method in advanced functions and + compiled cmdlets +- Engine errors such as `CommandNotFoundException` (calling a command that + doesn't exist) and `ParameterBindingException` (invalid parameter arguments) +- .NET method calls that throw exceptions, such as `[int]::Parse('abc')` + +```powershell +# Statement-terminating error: Get-Item fails, but the next statement runs +Get-Item -Path 'C:\NoSuchFile.txt' +Write-Output 'This still runs' +``` + +Statement-terminating errors can be caught by `try/catch` and `trap`. + +> [!NOTE] +> `.ThrowTerminatingError()` doesn't consult the `-ErrorAction` parameter +> (except for the `Break` value, which enters the debugger). However, +> `$ErrorActionPreference` _does_ apply to statement-terminating errors +> through the engine's statement-level handler. For example, +> `$ErrorActionPreference = 'SilentlyContinue'` can suppress a +> statement-terminating error so that the script continues at the next +> statement. The `-ErrorAction` parameter can't do this. For details, see +> [The $ErrorActionPreference asymmetry][05]. + +### Script-terminating errors + +A script-terminating error unwinds the entire call stack. Execution stops +completely unless the error is caught by a `try/catch` block or `trap` +statement. Script-terminating errors are generated by: + +- The `throw` keyword +- Parse errors (syntax errors that prevent the script from being compiled) +- Non-terminating errors **escalated** by `-ErrorAction Stop` or + `$ErrorActionPreference = 'Stop'` in non-advanced contexts. For more + information, see [How escalation works][01]. +- Certain critical engine failures + +```powershell +# 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)' +``` + +The `throw` keyword generates a script-terminating error by default. However, +`$ErrorActionPreference` _can_ suppress `throw` when set to `SilentlyContinue` +or `Ignore`. When calling an advanced function with +`-ErrorAction SilentlyContinue`, the parameter translates to a scope-local +`$ErrorActionPreference` value, so it also suppresses `throw` inside that +function. + +> [!NOTE] +> Even with `$ErrorActionPreference = 'Ignore'`, a `throw` that's suppressed +> still records an entry in `$Error`. The `Ignore` value only prevents `$Error` +> recording for **non-terminating** errors. + +> [!IMPORTANT] +> The terms _statement-terminating_ and _script-terminating_ describe the scope +> of impact, not the severity of the error. A statement-terminating error stops +> one statement. A script-terminating error stops the entire script and its +> callers. Both can be caught by `try/catch`. + +### External program errors + +External (native) programs don't participate in PowerShell's error system +directly. They report failure through a non-zero exit code, which PowerShell +stores in the `$LASTEXITCODE` automatic variable. + +```powershell +git clone https://example.com/nonexistent.git 2>$null +if ($LASTEXITCODE -ne 0) { + Write-Error "git failed with exit code $LASTEXITCODE" +} +``` + +By default, a non-zero exit code from a native program: + +- Sets `$?` to `$false` +- Does **not** generate an `ErrorRecord` in `$Error` +- Does **not** trigger `catch` or `trap` + +PowerShell 7.3 added the experimental preference variable +`$PSNativeCommandUseErrorActionPreference`, which became a stable feature in +7.4. When you set this variable to `$true`, it causes a non-zero exit code to +emit a **non-terminating error** whose message states the specific exit code (a +`NativeCommandExitException`). This error respects `$ErrorActionPreference`, so +setting it to `Stop` promotes the error to a script-terminating error that can +be caught with `try`/`catch`. + +## Error state variables + +PowerShell maintains several automatic variables that reflect the current error +state. + +### `$?` + +Contains `$true` if the last operation succeeded and `$false` if it produced +any error (non-terminating or terminating). For native commands, `$?` is set +based on the exit code: `$true` for exit code `0`, `$false` otherwise. + +```powershell +Get-Item -Path 'C:\NoSuchFile.txt' 2>$null +$? # False +``` + +### `$Error` + +An `ArrayList` that stores the most recent error records, with the most recent +error at index `0`. The list holds up to `$MaximumErrorCount` entries (default +256). + +All terminating errors are added to `$Error`. For terminating errors, `Ignore` +suppresses display but still records the error in `$Error`. All non-terminating +are added to `$Error` unless `-ErrorAction Ignore` is used on non-terminating +errors, which prevents both display and recording. + +### `$LASTEXITCODE` + +Contains the exit code of the last native program that ran. A value of `0` +conventionally indicates success. Any non-zero value indicates failure. This +variable isn't affected by PowerShell cmdlet errors. + +## Control error behavior + +### The `-ErrorAction` common parameter + +The `-ErrorAction` common parameter overrides `$ErrorActionPreference` for a +single command. It controls how PowerShell responds to **non-terminating** +errors from that command. + +| Value | Behavior | +| ------------------ | -------------------------------------------------------------------- | +| `Continue` | Display the error and continue (default) | +| `SilentlyContinue` | Suppress display, add to `$Error`, continue | +| `Ignore` | Suppress display and don't add to `$Error` | +| `Stop` | **Escalate** to a terminating error (see [How escalation works][01]) | +| `Inquire` | Prompt the user for a decision | +| `Break` | Enter the debugger | + +`-ErrorAction` doesn't change the behavior of errors generated by +`$PSCmdlet.ThrowTerminatingError()`. Those errors are always +statement-terminating regardless of the caller's preference. + +### The `$ErrorActionPreference `variable + +The `$ErrorActionPreference` preference variable applies to all commands in the +current scope and child scopes. It accepts the same values as `-ErrorAction`. + +```powershell +$ErrorActionPreference = 'Stop' +# All non-terminating errors in this scope now become terminating +Write-Error 'This now throws' # Generates ActionPreferenceStopException +``` + +When `-ErrorAction` is specified on a command, it takes precedence over +`$ErrorActionPreference` for that command. + +### How escalation works + +When `-ErrorAction Stop` or `$ErrorActionPreference = 'Stop'` is in effect, +PowerShell converts non-terminating errors into terminating errors using the +following mechanism: + +1. A cmdlet calls `WriteError()` internally to emit a non-terminating error. +1. The engine checks the effective `ErrorAction` preference for the command. +1. Because the preference is `Stop`, the engine creates an + `ActionPreferenceStopException` that wraps the original error record. +1. If caught by `catch`, the original error information is accessible through + `$_.Exception.ErrorRecord`. + +The scope of the escalated error depends on context: + +- In **non-advanced** scripts, functions, or script blocks, setting + `$ErrorActionPreference = 'Stop'` escalates to a **script-terminating** + error. The error propagates up the call stack. +- In **advanced** functions and script blocks (those with `[CmdletBinding()]`), + the error remains **statement-terminating**. Execution continues at the next + statement after the call. +- Passing `-ErrorAction Stop` to an advanced function has the same effect as + setting `$ErrorActionPreference = 'Stop'` inside it, because `-ErrorAction` + translates to a scope-local `$ErrorActionPreference` value. + +### Escalation examples + +- NON-advanced: script-terminating ('after' does NOT print) + + ```powershell + & { + param() + $ErrorActionPreference = 'Stop' + Get-Item 'NoSuchPath' + } 2>$null + 'after' + ``` + +- ADVANCED: statement-terminating ('after' DOES print) + + ```powershell + & { + [CmdletBinding()] + param() + $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' + } 2>$null + 'after' + ``` + +- Without `-ErrorAction Stop`: non-terminating, catch doesn't run + + ```powershell + try { + Write-Error 'This is non-terminating' + Write-Output 'Execution continues' + } catch { + Write-Output "Caught: $_" # Not reached + } + ``` + +- With `-ErrorAction Stop`: escalated to terminating + + ```powershell + try { + Write-Error 'This becomes terminating' -ErrorAction Stop + } catch { + Write-Output "Caught: $_" # Reached + } + ``` + +Escalated errors can be caught by their original exception type. The engine +unwraps the `ActionPreferenceStopException` to find the underlying exception: + +```powershell +try { + Get-Item -Path 'C:\NoSuchFile.txt' -ErrorAction Stop +} catch [System.Management.Automation.ItemNotFoundException] { + Write-Output "File not found: $($_.Exception.Message)" +} +``` + +### The `$ErrorActionPreference` asymmetry + +The `-ErrorAction` parameter and the `$ErrorActionPreference` variable behave +differently with terminating errors. It's important to understand this +asymmetry: + +- `-ErrorAction` only affects **non-terminating** errors. When a cmdlet calls + `$PSCmdlet.ThrowTerminatingError()`, the `-ErrorAction` parameter is ignored + (except for `Break`, which enters the debugger). The error is always thrown. + +- `$ErrorActionPreference` affects **both** non-terminating and + statement-terminating errors. The engine's statement-level error handler + reads `$ErrorActionPreference` (not the `-ErrorAction` parameter) and can + suppress a statement-terminating error when the value is `SilentlyContinue` + or `Ignore`. + +```powershell +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' +``` + +> [!IMPORTANT] +> `$ErrorActionPreference` can't suppress errors that have +> `SuppressPromptInInterpreter` set to `true`. These always propagate +> regardless of the preference variable. Examples of this type of error +> include: +> +> - `ActionPreferenceStopException` from `-ErrorAction Stop` escalation +> - Errors inside PowerShell class methods +> - `PipelineStoppedException` + +## Handle errors + +### `try/catch/finally` + +Use `try/catch/finally` to handle statement-terminating and script-terminating +errors. When an error occurs inside a `try` block, PowerShell searches for a +matching `catch` block. The `finally` block always runs, whether or not an +error occurred. + +```powershell +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 +} +``` + +Inside a `try` block, the engine sets an internal flag that causes non- +terminating errors escalated by `-ErrorAction Stop` or +`$ErrorActionPreference = 'Stop'` to propagate to the `catch` block. This +is designed behavior, not a special case. + +For full syntax details, see [about_Try_Catch_Finally][12]. + +### `trap` + +The `trap` statement handles terminating errors at the scope level. When an +error occurs anywhere in the enclosing scope, the `trap` block runs. + +- **Default** (no `break` or `continue`): The error is displayed and execution + continues at the next statement after the one that caused the error. +- **`continue`** in the trap: Suppresses the error message and resumes at the + next statement. +- **`break`** in the trap: The error propagates to the parent scope. + +```powershell +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' +``` + +For full syntax details, see [about_Trap][11]. + +## Reporting errors in functions and scripts + +When writing functions and scripts, choose the error-reporting mechanism that +matches the severity of the failure. + +### Non-terminating - use `Write-Error` + +Use `Write-Error` when the function can continue processing other input. This +is appropriate for pipeline functions that process multiple objects and +encounter failures on individual items. + +```powershell +function Test-Path-Safe { + [CmdletBinding()] + param([Parameter(ValueFromPipeline)][string]$Path) + process { + if (-not (Test-Path $Path)) { + Write-Error "Path not found: $Path" + return + } + $Path + } +} +``` + +> [!NOTE] +> In advanced functions (those with `[CmdletBinding()]`), use +> `$PSCmdlet.WriteError()` instead of `Write-Error` to ensure that `$?` is +> properly set to `$false` in the caller's scope. The `Write-Error` cmdlet +> doesn't always set `$?` correctly. + +### Statement-terminating - use `$PSCmdlet.ThrowTerminatingError()` + +Use `$PSCmdlet.ThrowTerminatingError()` when the function can't continue at all +but the caller should decide how to handle the failure. This is the recommended +approach in advanced functions. + +```powershell +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 +} +``` + +After the error leaves the function, the caller treats it as a non-terminating +error by default. The caller can escalate it with `-ErrorAction Stop`. + +### Script-terminating - use `throw` + +Use `throw` when recovery isn't possible and the entire script should stop. + +```powershell +$config = Get-Content 'config.json' -ErrorAction SilentlyContinue | + ConvertFrom-Json + +if (-not $config) { + throw 'Cannot proceed without a valid configuration file.' +} +``` + +### Which mechanism to use + +- When processing multiple inputs where some may fail, use `Write-Error` or + `$PSCmdlet.WriteError()`. +- If the function can't continue, use `$PSCmdlet.ThrowTerminatingError()` and + let the caller decide how to handle it. +- If the entire script must stop immediately, use `throw`. + +## Summary of error types + +The following tables summarize the properties and behaviors of the different +error types in PowerShell. + +### Non-terminating error + +[Non-terminating errors][02] can be generated by `Write-Error` or +`$PSCmdlet.WriteError()`. + +| Attribute | Description | +| ------------------------------------ | ------------------------------- | +| Scope of impact | Pipeline continues | +| Caught by `catch` | No (unless escalated) | +| Caught by `trap` | No (unless escalated) | +| Added to `$Error` | Yes (unless `Ignore`) | +| Sets `$?` to `$false` | Yes | +| Affected by `-ErrorAction` | Yes | +| Affected by `$ErrorActionPreference` | Yes | + +### Statement-terminating error + +[Statement-terminating errors][04] can be generated by +`ThrowTerminatingError()`, engine errors, .NET method exceptions, or +`-ErrorAction Stop` in advanced contexts. + +| Attribute | Description | +| ------------------------------------ | ----------------------------------------- | +| Scope of impact | Current statement stops; script continues | +| Caught by `catch` | Yes | +| Caught by `trap` | Yes | +| Added to `$Error` | Yes | +| Sets `$?` to `$false` | Yes | +| Affected by `-ErrorAction` | No (`Break` only) | +| Affected by `$ErrorActionPreference` | Yes (can suppress) | + +### Script-terminating error + +[Script-terminating errors][03] can be generated by `throw`, parse errors, or +`-ErrorAction Stop` in non-advanced contexts. + +| Attribute | Description | +| ------------------------------------ | ----------------------------- | +| Scope of impact | Call stack unwinds | +| Caught by `catch` | Yes | +| Caught by `trap` | Yes | +| Added to `$Error` | Yes | +| Sets `$?` to `$false` | Yes | +| Affected by `-ErrorAction` | No | +| Affected by `$ErrorActionPreference` | `throw`: Yes (can suppress) | +| Affected by `$ErrorActionPreference` | Escalated: depends on context | + +## See also + +- [about_Automatic_Variables][06] +- [about_CommonParameters][07] +- [about_Preference_Variables][09] +- [about_Output_Streams][08] +- [about_Throw][10] +- [about_Trap][11] +- [about_Try_Catch_Finally][12] + + +[01]: #how-escalation-works +[02]: #non-terminating-errors +[03]: #script-terminating-errors +[04]: #statement-terminating-errors +[05]: #the-erroractionpreference-asymmetry +[06]: about_Automatic_Variables.md +[07]: about_CommonParameters.md +[08]: about_Output_Streams.md +[09]: about_Preference_Variables.md +[10]: about_Throw.md +[11]: about_Trap.md +[12]: about_Try_Catch_Finally.md diff --git a/reference/7.5/Microsoft.PowerShell.Core/About/about_Preference_Variables.md b/reference/7.5/Microsoft.PowerShell.Core/About/about_Preference_Variables.md index 1e7626c2b1a8..66480d8a2a18 100644 --- a/reference/7.5/Microsoft.PowerShell.Core/About/about_Preference_Variables.md +++ b/reference/7.5/Microsoft.PowerShell.Core/About/about_Preference_Variables.md @@ -1,7 +1,7 @@ --- description: Variables that customize the behavior of PowerShell. Locale: en-US -ms.date: 12/01/2025 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7.5&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Preference_Variables @@ -388,25 +388,32 @@ The valid values are as follows: raised. - **Continue**: (Default) Displays the error message and continues executing. - **Ignore**: Suppresses the error message and continues to execute the - command. The **Ignore** value is intended for per-command use, not for use as - saved preference. **Ignore** isn't a valid value for the - `$ErrorActionPreference` variable. + command. Unlike **SilentlyContinue**, **Ignore** doesn't add the error + message to the `$Error` automatic variable. The **Ignore** value is also + valid for `$ErrorActionPreference`, where it suppresses both non-terminating + and statement-terminating errors. However, **Ignore** only prevents `$Error` + recording for non-terminating errors. Terminating errors that are suppressed + by `Ignore` are still recorded in `$Error`. - **Inquire**: Displays the error message and asks you whether you want to continue. - **SilentlyContinue**: No effect. The error message isn't displayed and execution continues without interruption. - **Stop**: Displays the error message and stops executing. In addition to the - error generated, the **Stop** value generates an ActionPreferenceStopException - object to the error stream. + error generated, the **Stop** value generates an + ActionPreferenceStopException object to the error stream. - **Suspend**: Automatically suspends a workflow job to allow for further investigation. After investigation, the workflow can be resumed. The **Suspend** value is intended for per-command use, not for use as saved preference. **Suspend** isn't a valid value for the `$ErrorActionPreference` variable. -`$ErrorActionPreference` and the **ErrorAction** parameter don't affect how -PowerShell responds to terminating errors that stop cmdlet processing. For more -information about the **ErrorAction** common parameter, see +`$ErrorActionPreference` applies to **both** non-terminating and +statement-terminating errors. Unlike the `-ErrorAction` parameter (which only +affects non-terminating errors), the preference variable can also suppress or +escalate errors generated by `$PSCmdlet.ThrowTerminatingError()`. When set to +**Stop**, it escalates non-terminating errors to script-terminating errors. For +more information about error categories, see [about_Error_Handling][67]. For +more information about the **ErrorAction** common parameter, see [about_CommonParameters][29]. Many native commands write to `stderr` as an alternative stream for additional @@ -419,10 +426,9 @@ like when using redirection operators (`2>&1`), aren't written to the `$Error` variable and the preference variable `$ErrorActionPreference` doesn't affect the redirected output. -PowerShell 7.3 added an experimental feature that allows you to control how -messages written to `stderr` are handled. - -For more information see, [$PSNativeCommandUseErrorActionPreference][18]. +PowerShell 7.4 added a feature that allows you to control how messages written +to `stderr` are handled. For more information, see +[$PSNativeCommandUseErrorActionPreference][18]. ### Examples @@ -1692,6 +1698,7 @@ At line:1 char:1 - [about_Automatic_Variables][28] - [about_CommonParameters][29] - [about_Environment_Variables][30] +- [about_Error_Handling][67] - [about_Profiles][36] - [about_Remote][39] - [about_Scopes][40] @@ -1763,3 +1770,4 @@ At line:1 char:1 [64]: xref:System.Text.UTF7Encoding [65]: xref:System.Text.UTF8Encoding [66]: about_Functions_CmdletBindingAttribute.md +[67]: about_Error_Handling.md diff --git a/reference/7.5/Microsoft.PowerShell.Core/About/about_Throw.md b/reference/7.5/Microsoft.PowerShell.Core/About/about_Throw.md index de3604500a84..b4c853e26cdb 100644 --- a/reference/7.5/Microsoft.PowerShell.Core/About/about_Throw.md +++ b/reference/7.5/Microsoft.PowerShell.Core/About/about_Throw.md @@ -1,7 +1,7 @@ --- -description: Describes the `throw` keyword, which generates a terminating error. +description: Describes the `throw` keyword, which generates a script-terminating error by default. Locale: en-US -ms.date: 01/18/2026 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_throw?view=powershell-7.5&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Throw @@ -10,12 +10,30 @@ title: about_Throw ## Short description -Describes the `throw` keyword that generates a terminating error. +Describes the `throw` keyword, which generates a script-terminating error by +default. ## Long description -The `throw` keyword causes a terminating error. You can use the `throw` keyword -to stop the processing of a command, function, or script. +The `throw` keyword causes a script-terminating error by default. You can use +the `throw` keyword to stop the processing of a command, function, or script. + +Unlike statement-terminating errors, the `throw` keyword unwinds the entire +call stack. Execution stops completely unless the error is caught by a +`try/catch` block or `trap` statement. + +> [!NOTE] +> `$ErrorActionPreference` can suppress `throw`. When set to `SilentlyContinue` +> or `Ignore`, the error doesn't propagate and execution continues at the next +> statement. When calling an advanced function with +> `-ErrorAction SilentlyContinue`, the parameter translates to a scope-local +> `$ErrorActionPreference` value, so it also suppresses `throw` inside that +> function. Even when suppressed, `throw` still records an entry in `$Error`. +> The `Ignore` value only prevents `$Error` recording for non-terminating +> errors like those generated by `$PSCmdlet.ThrowTerminatingError()`. + +For more information about error categories and `$ErrorActionPreference` +behavior, see [about_Error_Handling][03]. For example, you can use the `throw` keyword in the statement block of an `if` statement to respond to a condition or in the `catch` block of a @@ -46,7 +64,7 @@ Exception: ScriptHalted If the `throw` keyword is used in a `catch` block without an expression, it throws the current RuntimeException again. For more information, see -[about_Try_Catch_Finally](about_Try_Catch_Finally.md). +[about_Try_Catch_Finally][07]. ## Throwing a string @@ -116,13 +134,23 @@ object is automatically saved in the `$Error` automatic variable. Unlike past versions of PowerShell, don't use the `throw` keyword for parameter validation. See -[about_Functions_Advanced_Parameters](about_Functions_Advanced_Parameters.md) +[about_Functions_Advanced_Parameters][04] for the correct way. ## See also -- [about_Break](about_Break.md) -- [about_Continue](about_Continue.md) -- [about_Scopes](about_Scopes.md) -- [about_Trap](about_Trap.md) -- [about_Try_Catch_Finally](about_Try_Catch_Finally.md) +- [about_Break][01] +- [about_Continue][02] +- [about_Error_Handling][03] +- [about_Scopes][05] +- [about_Trap][06] +- [about_Try_Catch_Finally][07] + + +[01]: about_Break.md +[02]: about_Continue.md +[03]: about_Error_Handling.md +[04]: about_Functions_Advanced_Parameters.md +[05]: about_Scopes.md +[06]: about_Trap.md +[07]: about_Try_Catch_Finally.md diff --git a/reference/7.5/Microsoft.PowerShell.Core/About/about_Trap.md b/reference/7.5/Microsoft.PowerShell.Core/About/about_Trap.md index 37514e43fdc9..dea91ef86e21 100644 --- a/reference/7.5/Microsoft.PowerShell.Core/About/about_Trap.md +++ b/reference/7.5/Microsoft.PowerShell.Core/About/about_Trap.md @@ -1,7 +1,7 @@ --- -description: Describes a keyword that handles a terminating error. +description: Describes a keyword that handles statement-terminating and script-terminating errors. Locale: en-US -ms.date: 01/13/2026 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_trap?view=powershell-7.5&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Trap @@ -10,14 +10,16 @@ title: about_Trap ## Short description -Describes a keyword that handles a terminating error. +Describes a keyword that handles statement-terminating and script-terminating +errors. ## Long description -A terminating error stops a statement from running. If PowerShell doesn't -handle a terminating error in some way, PowerShell also stops running the -function or script in the current pipeline. In other languages, such as C#, -terminating errors are known as exceptions. +A terminating error stops a statement from running. PowerShell distinguishes +_statement-terminating_ errors (which stop only the current statement) from +_script-terminating_ errors (which unwind the entire call stack). The `trap` +keyword can handle both kinds. For more information about error categories, see +[about_Error_Handling][07]. The `trap` keyword specifies a list of statements to run when a terminating error occurs. `trap` statements can handle the terminating errors in the @@ -286,7 +288,7 @@ after loop In the output, you can see the loops continue until the last iteration. When the script tries to divide 1 by 0, PowerShell throws a terminating error. The -script skips the rest of the `foreach` statement, runs the `try` statement, +script skips the rest of the `foreach` statement, runs the `trap` statement, and continues after the `foreach` statement. ## Trapping errors and scope @@ -468,6 +470,7 @@ statement. For more information, see - [about_Break][01] - [about_Continue][02] +- [about_Error_Handling][07] - [about_Scopes][03] - [about_Throw][04] - [about_Try_Catch_Finally][05] @@ -479,3 +482,4 @@ statement. For more information, see [04]: about_Throw.md [05]: about_Try_Catch_Finally.md [06]: https://wikipedia.org/wiki/JavaScript_syntax#hoisting +[07]: about_Error_Handling.md diff --git a/reference/7.5/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md b/reference/7.5/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md index 676b01d71791..f422b8fab6b9 100644 --- a/reference/7.5/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md +++ b/reference/7.5/Microsoft.PowerShell.Core/About/about_Try_Catch_Finally.md @@ -1,7 +1,7 @@ --- -description: Describes how to use the `try`, `catch`, and `finally` blocks to handle terminating errors. +description: Describes how to use the `try`, `catch`, and `finally` blocks to handle statement-terminating and script-terminating errors. Locale: en-US -ms.date: 01/13/2026 +ms.date: 04/02/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_try_catch_finally?view=powershell-7.5&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Try_Catch_Finally @@ -11,18 +11,31 @@ title: about_Try_Catch_Finally ## Short description Describes how to use the `try`, `catch`, and `finally` blocks to handle -terminating errors. +statement-terminating and script-terminating errors. ## Long description Use `try`, `catch`, and `finally` blocks to respond to or handle terminating -errors in scripts. The `trap` statement can also be used to handle terminating -errors in scripts. For more information, see [about_Trap][05]. +errors in scripts. PowerShell has two kinds of terminating errors: -A terminating error stops a statement from running. If PowerShell does not -handle a terminating error in some way, PowerShell also stops running the -function or script using the current pipeline. In other languages, such as C\#, -terminating errors are referred to as exceptions. +- _statement-terminating_ errors that stop the current statement and +- _script-terminating_ errors that unwind the entire call stack + +Both kinds are caught by `try/catch`. You can also use the `trap` statement to +handle terminating errors. For more information, see [about_Trap][05]. For a +comprehensive overview of all error types, see [about_Error_Handling][06]. + +A statement-terminating error stops the current statement from running, but +PowerShell continues at the next statement unless the error is also +script-terminating. A script-terminating error (such as an error produced by +the `throw` keyword) stops the entire script unless caught by a `try/catch` +block or `trap` statement. + +> [!NOTE] +> `$ErrorActionPreference` can suppress `throw`. When set to `SilentlyContinue` +> or `Ignore`, the error doesn't propagate and execution continues at the next +> statement. For details, see the _Script-terminating errors_ section of +> [about_Error_Handling][07]. Use the `try` block to define a section of a script in which you want PowerShell to monitor for errors. When an error occurs within the `try` block, @@ -255,7 +268,7 @@ try { "An error occurred that could not be resolved." } finally { $wc.Dispose() - if (Test-Path $tempPath) { Remove-Item $tempFile } + if (Test-Path $tempFile) { Remove-Item $tempFile } } ``` @@ -263,6 +276,7 @@ try { - [about_Break][01] - [about_Continue][02] +- [about_Error_Handling][06] - [about_Scopes][03] - [about_Throw][04] - [about_Trap][05] @@ -273,3 +287,5 @@ try { [03]: about_Scopes.md [04]: about_Throw.md [05]: about_Trap.md +[06]: about_Error_Handling.md +[07]: about_Error_Handling.md#script-terminating-errors diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md index 7e76f45b7d26..940162af2f94 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Preference_Variables.md @@ -426,10 +426,9 @@ like when using redirection operators (`2>&1`), aren't written to the `$Error` variable and the preference variable `$ErrorActionPreference` doesn't affect the redirected output. -PowerShell 7.3 added an experimental feature that allows you to control how -messages written to `stderr` are handled. - -For more information see, [$PSNativeCommandUseErrorActionPreference][18]. +PowerShell 7.4 added a feature that allows you to control how messages written +to `stderr` are handled. For more information, see +[$PSNativeCommandUseErrorActionPreference][18]. ### Examples diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md index cc223479c797..e1db32919223 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Throw.md @@ -33,7 +33,7 @@ call stack. Execution stops completely unless the error is caught by a > errors like those generated by `$PSCmdlet.ThrowTerminatingError()`. For more information about error categories and `$ErrorActionPreference` -behavior, see [about_Error_Handling](about_Error_Handling.md). +behavior, see [about_Error_Handling][03]. For example, you can use the `throw` keyword in the statement block of an `if` statement to respond to a condition or in the `catch` block of a @@ -64,7 +64,7 @@ Exception: ScriptHalted If the `throw` keyword is used in a `catch` block without an expression, it throws the current RuntimeException again. For more information, see -[about_Try_Catch_Finally](about_Try_Catch_Finally.md). +[about_Try_Catch_Finally][07]. ## Throwing a string @@ -134,14 +134,23 @@ object is automatically saved in the `$Error` automatic variable. Unlike past versions of PowerShell, don't use the `throw` keyword for parameter validation. See -[about_Functions_Advanced_Parameters](about_Functions_Advanced_Parameters.md) +[about_Functions_Advanced_Parameters][04] for the correct way. ## See also -- [about_Break](about_Break.md) -- [about_Continue](about_Continue.md) -- [about_Error_Handling](about_Error_Handling.md) -- [about_Scopes](about_Scopes.md) -- [about_Trap](about_Trap.md) -- [about_Try_Catch_Finally](about_Try_Catch_Finally.md) +- [about_Break][01] +- [about_Continue][02] +- [about_Error_Handling][03] +- [about_Scopes][05] +- [about_Trap][06] +- [about_Try_Catch_Finally][07] + + +[01]: about_Break.md +[02]: about_Continue.md +[03]: about_Error_Handling.md +[04]: about_Functions_Advanced_Parameters.md +[05]: about_Scopes.md +[06]: about_Trap.md +[07]: about_Try_Catch_Finally.md