Skip to content

Commit f25403c

Browse files
SufficientDaikonclaude
authored andcommitted
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 <noreply@anthropic.com>
1 parent 4f51cce commit f25403c

File tree

1 file changed

+39
-10
lines changed

1 file changed

+39
-10
lines changed

reference/7.6/Microsoft.PowerShell.Core/About/about_Error_Handling.md

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ statement. Script-terminating errors are generated by:
8989
- The `throw` keyword
9090
- Parse errors (syntax errors that prevent the script from being compiled)
9191
- Non-terminating errors **escalated** by `-ErrorAction Stop` or
92-
`$ErrorActionPreference = 'Stop'` (see [How escalation works][05])
92+
`$ErrorActionPreference = 'Stop'` in non-advanced contexts (see
93+
[How escalation works][05])
9394
- Certain critical engine failures
9495

9596
```powershell
@@ -103,9 +104,17 @@ Test-Throw
103104
Write-Output 'This never runs either (unless caught)'
104105
```
105106

106-
The `throw` keyword always generates a script-terminating error regardless of
107-
`$ErrorActionPreference`. Setting `$ErrorActionPreference` to
108-
`SilentlyContinue` or `Ignore` cannot suppress a `throw`.
107+
The `throw` keyword generates a script-terminating error by default.
108+
However, `$ErrorActionPreference` _can_ suppress `throw` when set to
109+
`SilentlyContinue` or `Ignore`. When calling an advanced function with
110+
`-ErrorAction SilentlyContinue`, the parameter translates to a scope-local
111+
`$ErrorActionPreference` value, so it also suppresses `throw` inside that
112+
function.
113+
114+
> [!NOTE]
115+
> Even with `$ErrorActionPreference = 'Ignore'`, a `throw` that is suppressed
116+
> still records an entry in `$Error`. The `Ignore` value only prevents
117+
> `$Error` recording for **non-terminating** errors.
109118
110119
> [!IMPORTANT]
111120
> 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
209218
### How escalation works
210219

211220
When `-ErrorAction Stop` or `$ErrorActionPreference = 'Stop'` is in effect,
212-
PowerShell converts non-terminating errors into script-terminating errors
213-
using the following mechanism:
221+
PowerShell converts non-terminating errors into terminating errors using the
222+
following mechanism:
214223

215224
1. A cmdlet calls `WriteError()` internally to emit a non-terminating error.
216225
1. The engine checks the effective `ErrorAction` preference for the command.
217226
1. Because the preference is `Stop`, the engine creates an
218227
`ActionPreferenceStopException` that wraps the original error record.
219-
1. This exception has `SuppressPromptInInterpreter` set to `true`, which
220-
causes it to propagate up the call stack like a script-terminating error.
221228
1. If caught by `catch`, the original error information is accessible through
222229
`$_.Exception.ErrorRecord`.
223230

231+
The scope of the escalated error depends on context:
232+
233+
- In **non-advanced** scripts, functions, or script blocks,
234+
`$ErrorActionPreference = 'Stop'` escalates to a **script-terminating**
235+
error. The error propagates up the call stack.
236+
- In **advanced** functions and script blocks (those with `[CmdletBinding()]`),
237+
the error remains **statement-terminating**. Execution continues at the
238+
next statement after the call.
239+
- Passing `-ErrorAction Stop` to an advanced function has the same effect as
240+
setting `$ErrorActionPreference = 'Stop'` inside it, because `-ErrorAction`
241+
translates to a scope-local `$ErrorActionPreference` value.
242+
243+
```powershell
244+
# NON-advanced: script-terminating ('after' does NOT print)
245+
& { param() $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' } 2>$null
246+
'after'
247+
248+
# ADVANCED: statement-terminating ('after' DOES print)
249+
& { [CmdletBinding()]param() $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' } 2>$null
250+
'after'
251+
```
252+
224253
```powershell
225254
try {
226255
# Without -ErrorAction Stop: non-terminating, catch does not fire
@@ -433,14 +462,14 @@ if (-not $config) {
433462

434463
| Property | Non-terminating | Statement-terminating | Script-terminating |
435464
|----------|----------------|----------------------|-------------------|
436-
| Generated by | `Write-Error`, `WriteError()` | `ThrowTerminatingError()`, engine errors, .NET method exceptions | `throw`, parse errors, `-ErrorAction Stop` escalation |
465+
| 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 |
437466
| Scope of impact | Pipeline continues | Current statement stops; script continues | Call stack unwinds |
438467
| Caught by `catch` | No (unless escalated) | Yes | Yes |
439468
| Caught by `trap` | No (unless escalated) | Yes | Yes |
440469
| Added to `$Error` | Yes (unless `Ignore`) | Yes | Yes |
441470
| Sets `$?` to `$false` | Yes | Yes | Yes |
442471
| Affected by `-ErrorAction` | Yes | No (`Break` only) | No |
443-
| Affected by `$ErrorActionPreference` | Yes | Yes (can suppress) | `throw`: No; escalated: No |
472+
| Affected by `$ErrorActionPreference` | Yes | Yes (can suppress) | `throw`: Yes (can suppress); escalated: depends on context |
444473

445474
## See also
446475

0 commit comments

Comments
 (0)