Catching the PowerShell error stream

One of the challenges with PowerShell is the merging of concepts into a single DSL. In regards to error messaging, we have $LASTEXITCODE, PowerShell / .NET (throw) and the error stream (Write-Error). I tend to avoid using Write-Error and prefer to use throw instead, however I do use powershell modules which use Write-Error and I want to be able to handle these when it makes sense.

The following code:

Write-Host "Standard catch:" -ForegroundColor Cyan
try {
    Write-Error "writing to the error stream"
    Write-Host "I've been caught" 

Produces the following output:

Standard catch:C:\users\naeemk\desktop\error_stream.ps1 : writing to the error stream
At line:1 char:1
+ .\error_stream.ps1
+ ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,error_stream.ps1

This behaviour was unexpected when I first encountered it. Today I stumbled upon a tidy way to handle the error: by Stopping and Catching. If we set an ErrorAction of Stop to the problem call, we are able to catch the error stream properly.

Write-Host "Stop and Catch:" -ForegroundColor Cyan
try {
    Write-Error "writing to the error stream" -ErrorAction Stop
    Write-Host ("I've been caught: {0}" -f $_)

Which produces the expected output:

Stop and Catch:
I've been caught: writing to the error stream

In our case we were running this code inside a parallel runspace and the unhandled call to the error stream was crashing the runspace and giving us the wrong stacktrace. With this we can raise a PowerShell exception and marshall over the correct stacktrace to help with debugging.

blog comments powered by Disqus