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.
