I'm a C# developer and sometimes PowerShell is just driving me mad.
I have the following code:
$script:ErrorActionPreference = 'Stop'
try {
# Some code here
}
catch [Microsoft.PowerShell.Commands.WriteErrorException] {
# Print error messages (without stacktrace)
Write-Host -ForegroundColor Red $_.Exception.Message
exit 1
}
catch [System.Management.Automation.RuntimeException] {
# A thrown string
Write-Host -ForegroundColor Red $_.Exception.Message
Write-Host -ForegroundColor Red $_.ScriptStackTrace
exit 1
}
catch {
# Print proper exception message (including stack trace)
Write-Host -ForegroundColor Red "$($_.Exception.GetType().Name): $($_.Exception.Message)"
Write-Host -ForegroundColor Red $_.ScriptStackTrace
exit 1
}
The idea is basically:
- If the exception comes from a call to
Write-Erroruse the first catch block. - If a string is thrown directly, use the second catch block.
- For any other exception, use the last catch block.
Now, my problem is with Write-Error and the first catch block:
- If I call
Write-Errorwithin thetryblock, the second catch block is executed (even though the first one should be executed). - If I remove the second catch block and then call
Write-Error, the correct (first) catch block is used.
Why is that?
I've checked whether WriteErrorException and RuntimeException are inheriting from each other: They don't (both inherit from SystemException but this shouldn't matter).
I've also verified that this behavior is the same in both PowerShell 5.1 and PowerShell Core (6.0).
Write-Errorlook like? You can specify the exception thrown by it. When just doingWrite-Error 'msg' -ea 1, no exception is thrown, but an error record is under$Error.ErrorRecord, which is pretty weird. The source of the parent error record isSystem.Management.Automationwhich might be the cause of your issue.Write-Error 'some message'. It'll raise an exception because of$script:ErrorActionPreference = 'Stop'at the beginning of the script.Write-ErrorI can catch something (doesn't matter to me what you want to call it) and I can catch the correct ... thing of typeMicrosoft.PowerShell.Commands.WriteErrorExceptionif I remove the second catch block.-Exceptionto yourWrite-Errorargument list. PowerShell works with theErrorRecord.net class instead of justException. You can look upErrorRecordon the msdn.