Update: From an anonymous commenter, evidently error handing when using "-erroraction Stop" now works as one would expect in PowerShell version 3! However, if you're still using version 2 the information below should help you out.
When planning for exception handling, I’ve recently learned that forcing execution to stop by setting $erroractionpreference to ‘Stop’ or by using the –erroraction common parameter requires some special handling.
First let’s see what doesn’t work even though it seems like it should. Handling a normal terminating error is fairly straightforward:
Here we encountered an exception, got the exception’s type by inspecting the first element in the typenames member of the first error record’s exception’s base object, and then used that type name to catch the exception. This worked whether or not we specified the –ea or –erroraction parameter. This works because a ParameterBindingException is a terminating error. However, let’s see what happens when we try the same thing with an error that isn’t of terminating error family:
Hmm, bugger. We tried the same pattern, but this time it just doesn’t work. But…why? Without getting too long winded about it, I tried looking back through the automatic $error variable but couldn’t find an answer. So I tried a different tactic:
Aha! When we use –erroraction stop, the terminating exception isn’t the error that was encountered but an exception of type System.Management.Automation.ActionPreferencesStopException! But…wait, if that’s true, how do we know what type of error was encountered? Almost inexplicably the automatic variable $_ is set to the error record of the error that was encountered. If you know why, please share in the comments or send me an e-mail. Anyway, we can use that to re-throw the error as a terminating exception that can be caught and handled:
Basically we just wrap our command that makes use of the –erroraction stop inside two try/catch blocks. The inner block is used to trap the ActionPreferenceStopException generated by the erroraction parameter. In the inner catch block we throw the exception for the error that was caught which is then caught by the outer catch block statements and can the be handled. So, let’s finish with a generic pattern that one could turn into a code snippet or something:
And with that, Happy Friday!