4
votes

I am running the following power shell script using power shell console:

$ob1 = "nonexistingclass"
$a = new-object $ob1 
Write-Output "Created new object"
Write-Output "End"

This prints the error. And then continues and prints the "Created new object" and "End". So I am assuming this is a non terminating error.

But if I put try catch block around the new-object as follows:

$ob1 = "nonexistingclass"
try
{
    $a = new-object $ob1 
    Write-Output "Created new object"
}
catch
{ 
    Write-Error "Exception Message: $($_.Exception.Message)"     
}
Write-Output "End"

In this case catch block is hit and it writes the exception message.

My questions are:

  1. Is this a non terminating error? It looks like a non terminating error as the execution continues after the error (when there is no try catch block).
  2. If this is non terminating error why catch block is getting hit when I add the try catch block? My understanding is catch block will be executed only for terminating errors.
  3. Even when I invoke new-object in the first example (without try catch block) with -ErrorAction Stop, it still continues execution and prints the last 2 line. When I use -ErrorAction stop I am expecting that it should throw a terminating exception and the script execution should stop. Is my understanding wrong?
2

2 Answers

5
votes

Terminating errors don't always mean that the script will stop executing, it usually just means that they throw a PipelineStoppedException, meaning that processing will stop on that pipeline, but will continue executing the rest of the script. So to answer your questions, yes, it is a terminating error, but it is not stopping the execution of the entire script, this is why it hits the catch block.

The -ErrorAction stop switch just effectively makes the cmdlet throw a terminating error so that you can catch the error, it will not stop the script (hence why your last line is still executed). If you want the script to stop you would put the Exit command in the catch block to end the script at that point.

See:

Terminating Errors

Non-Terminating Errors

1
votes

According to the documentation, there are two types of PowerShell errors, terminating and non-terminating.

There is yet another obscure third type of errors. Such errors are caught by try and trap, i.e. they behave like terminating, but they do not stop execution without try or trap, i.e. they behave like non-terminating.

For example, if a command name is not recognized as the name of a cmdlet, function, script file, or operable program then PowerShell emits an error. Is this error terminating or not? It depends. By default it is not, surprisingly.

It looks like constant use of either error action preference Stop or try or trap blocks in scripts is a good idea. Otherwise semi-terminating errors may cause problems because invocation continues. Note that the default error action preference is Continue.

Examples of semi-terminating errors:

  1. A command is not found.
  2. Division by zero.
  3. Calling .NET methods with wrong arguments.
  4. PowerShell cannot convert data to some type.
  5. A .NET type is not found. (NB Your case)
  6. A property is not found in the strict mode.
  7. A variable is not found in the strict mode.
  8. A command parameter is not found.
  9. Assignment to not writable variables.
  10. Not supported provider features.
  11. A .NET exception.

The list may continue...

Hypothesis

The tests give the idea that any runtime exception is a semi-terminating error.

See the full case with test scripts - PowerShellTraps/Errors-of-unusual-type


UPDATE (as discussed in comments):

There is not much official documentation about such error details. But here is the comprehensive discussion at the PowerShell documentation repository:

https://github.com/MicrosoftDocs/PowerShell-Docs/issues/1583