I am learning PowerShell these days and have come across some odd behavior. After running the following code, whose only purpose is to understand exception handling:
try
{
throw [System.IO.FileNotFoundException]::new("Thrown a file not found exception")
}
catch [System.Management.Automation.RuntimeException]
{
Write-Output "Entered catch"
}
I get that "Entered catch" is shown onscreen. Why does this happen, if according to online documentation System.IO.FileNotFoundException does not have System.Management.Automation.RuntimeException in its line of inheritance? In other words, I was expecting the exception not to be caught and the corresponding exception error message to be seen onscreen instead.
CodePudding user response:
The behavior, present up to at least PowerShell Core 7.2.0-rc.1 (current as of this writing), is arguably a bug.
As you state, the
System.Management.Automation.RuntimeException
exception type is not a base class ofSystem.IO.FileNotFoundException
, and therefore shouldn't trigger thecatch
block.The problem has been reported in GitHub issue #16392
That said, catching
System.Management.Automation.RuntimeException
is virtually pointless, as it is the (conceptually speaking) abstract base class for specific PowerShell exception types such as, say,System.Management.Automation.CommandNotFoundException
.[1]
In practice, catch [System.Management.Automation.RuntimeException]
seems to behave like an unqualified catch
, i.e. it catches any exception (not caught by another, more specific, typed catch
block, if present).
If, at a high level, you need to distinguish between exception types derived from System.Management.Automation.RuntimeException
vs. those that aren't, you can use an unqualified catch
block in which you can use -is
, the type(-inheritance) / interface test operator:
try
{
throw [System.IO.FileNotFoundException]::new("Thrown a file not found exception")
}
catch {
$isPSException = $_.Exception -is [System.Management.Automation.RuntimeException]
"Exception is RuntimeException-derived: $isPSException"
}
[1] A rare example of where System.Management.Automation.RuntimeException
is used directly is the statement-terminating error triggered by 1 / 0