Home > Mobile >  Powershell trap with error in an if conditional statement
Powershell trap with error in an if conditional statement

Time:09-17

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.

  • Related