Share via


Why does catch not catch?

I ran into an interesting discussion with my customer today.  He was writing a code block that looked like the following:

 Try {
Get-MailboxServer Bogus
}
Catch {
"Mailbox server doesn't exist"
}

Looking at the code, it’s very simple. Run a command in try block and if error is generated, report on it using catch. However, it didn’t work as it should. That’s why it became interesting.

I tried the following:

 Try {
somestring
}
Catch {
"Error"
}

Now that worked just as you would expect!

What was going on here. I was puzzled and so was the engineer who asked me about the error in first place. So we looked at the about_Try_Catch_Finally on TechNet. As an IT Pro would usually RTFM, we went straight to examples and that looked just like our problem child. No issues when we run that example but when we run our code, it doesn’t want to work.

Again, as any other IT Pro would do, we did the next “logical” thing to match the example code with ours and decided we weren’t specifying error type. While we both agreed that it wasn’t the case, we still wanted to make sure. So we looked at the error object:

 $Error[0].Exception.gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     RemoteException                          System.Management.Automation.RuntimeException

Then we changed out Catch statement to specify the error type. That, as you may have guess it by now, didn’t work either! Smile

This is actually when we started paying attention to TFM. If we ever read the description on the TechNet documentation, it reads “Describes how to use the Try, Catch, and Finally blocks to handle terminating errors.”

So very clearly, it says the error must be a terminating error. And the errors we were generating when executing Get-MailboxServer cmdlet, were not terminating errors! As they say it all the time, once you find the issue, fix takes only seconds. All we had to do at this point was to make the error a terminating error:

 Try {
Get-MailboxServer Bogus -ErrorAction Stop
}
Catch {
"Mailbox server doesn't exist"
}

And the world was fine once again.