Here is my testing script:
trap {"trapped"}
if ($true) {
nonsenseString1
exit 0
}
nonsenseString2
and the result is:
trapped
nonsenseString1 : The term 'nonsenseString1' is not recognized ...
trapped
nonsenseString2 : The term 'nonsenseString2' is not recognized ...
If this not what I wanted and what I expected. After it trapped nonsenseString1
, it should exit 0
, why it doesn't? This happens in both powershell 5 and 7.
I discovered this has to do with the if conditional block. If I take off the block, then it behaves as I expected.
PS: My real purpose was to record any errors that may happen on a Powershell script, and people tell me that I should use Start-Transcript
:
How do I redirect stdout and stderr inside a powershell script?
Since I do not know when the error happens, I want to Stop-Transcript
in a trap.
CodePudding user response:
Selectively use a try
/ catch
/ finally
statement to act on a terminating error caused by an individual statement (see also the bottom section):
$trapActions = { "trapped" }
trap { & $trapActions }
if ($true) {
try {
nonsenseString1
} catch {
$_ | Write-Error
& $trapActions
exit 1
}
}
nonsenseString2
Note that I'm using exit 1
, because by convention failure is signaled with a nonzero exit code.
Note that trap
only acts on terminating errors (both statement and script-terminating ones), not also on the more typical non-terminating errors.
If it's acceptable to exit on the first terminating error - wherever it occurs - you can simply use trap { "trapped"; break }
in your original code.
As for what you tried:
The problem is indeed that, when a trap
statement is triggered, the enclosing block ({ ... }
) is exited, so that the exit 0
never executes; instead, execution resumes with the first statement after the block, so that nonsenseString2
executes too.
This mirrors the behavior of the try { ... } catch { ... } finally { ... }
statement, which was introduced later than trap
, and is nowadays typically used in lieu of the latter.
That is, as soon as a terminating error occurs inside the try
block, control is transferred to the catch
block, with any remaining statements in the try
block not getting executed.