In this great article Keith explains the difference between terminating and non-terminating errors in Powershell. According to Keith exceptions thrown from calls to a member of a .NET object or type are non-terminating errors.
Indeed if we define this .NET class for testing:
$a = Add-Type 'public class bla { public static void bl() { throw new System.ApplicationException("test"); }}' -PassThru
And then this function:
function tst { 1 | write-host; $a::bl(); 2 | Write-host }
we will see that when tst function is called the exception appears to be non-terminating: the second Write-Host
works.
But consider this:
function tst2 { try { tst } catch { "Catch!" } }
If we open the documentation, we can read that the catch responds to or handles terminating errors in scripts. Throughout the text of the articles the errors the article is dealing with qualified as "terminating" in numerous places.
So when we run the line above the second Write-Host does NOT run but the catch block does. It seems that our non-terminating error suddenly becomes terminating.
How come?
Another observation, is that with good old trap it's still non-terminating error:
function tst3 { tst trap { "Trap!" } }
Now, from practical perspective, what I want to achieve is the following. In a block of code I want to terminate on exceptions thrown from the .NET code. I want to leave terminating errors from cmdlets terminating and non-terminating errors from cmdlets non-terminating.
How do I achieve this?
Example:
Do-Something
Call::Something()
Do-SomethingElse
Call::SomethingElse()
Do-YetMoreSomething
Call::YetMoreSomething()
I want to terminate on all the exceptions from .NET calls above. I also want to terminate on terminating errors from the cmdlets. I do not want to terminate on non-terminating errors from the cmdlets.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…