I have been trying to wrap my head around extending Exceptions in PowerShell. My first pass at a class looks like this...
class CustomException : Exception {
CustomException () {
}
CustomException ([String] $message) : base ($message) {
}
}
And use is as expected, with the first approach here producing the type name, and the second the provided message...
try {
throw [CustomException]
} catch {
"$($_.Exception.Message)"
}
try {
throw [CustomException] 'Another message'
} catch {
"$($_.Exception.Message)"
}
However, I really want to have a default message, so I can use the first example in many places, but if I want to revise the message I can do it the one time in the class. Or perhaps even localize the message at some point. This thread seems to suggest it's possible in C#, especially the last two posts. So, taking the last example there...
public class MyException : Exception
{
public MyException () : base("This is my Custom Exception Message")
{
}
}
I thought I could do the same in Powershell, like so...
CustomException () : base ('Default message') {
}
But I still get the type name when not providing a message. That got me thinking, and I tried...
try {
throw [System.IO.FileNotFoundException]
} catch {
"$($_.Exception.Message)"
}
And that ALSO doesn't provide a default message, just the class name. So, is that C# code not doing what I think it's doing? Or is this just a difference in behavior in Powershell? Or am I doing something wrong?
What you want is perfectly supported, but you need to throw an instance of the exception!
The syntax of throw
is basically:
throw [Throwable]
where Throwable
is either an ErrorRecord, an Exception, or a string (a bare error message basically).
When you throw the type literal [CustomException]
, PowerShell converts that expression to a [string]
, which is why you just see the type name in the catch block.
Correctly throwing an exception instance requires you to call the constructor:
class CustomException : Exception
{
CustomException() : base("default CustomException message goes here")
{
}
}
try {
throw [CustomException]::new() # <-- don't forget to call the constructor
} catch {
"$_"
}