Home > other >  How to catch an error that is being reported on information stream?
How to catch an error that is being reported on information stream?

Time:06-18

I am using Weird-Cmd that has been written by someone else. This command searches the database for things and accepts certain parameters for its -Filter.

If I pass a bogus filter parameter, it returns a message telling me there's no such filter parameter.

That message is reported on Information stream (6). How do I invoke this cmdlet inside a try/catch and catch this error that is being reported on Information stream.

I tried redirecting the stream but it turned out PowerShell doesn't redirect except to Output/Success.

I do not have access to Weird-Cmd so I can't change it. I am limited to PowerShell 5.1.

Here is the message I get:

System.Management.Automation.ParentContainsErrorRecordException: Cannot bind parameter 'Filter' to the target. Exception setting "Filter": ""BogusProp" is not a recognized filterable property. Valid property names are: Prop1, Prop2,...."

CodePudding user response:

Assuming that Weird-Cmd is a cmdlet or an advanced function or script, use the common -InformationVariable parameter to capture the information stream's output:

try {
  Weird-Cmd -InformationVariable inf # Note: NO "$" before "inf"
  if ($inf) { throw $inf }
} catch {
  # ... handle the exception.
}

Otherwise - which includes invoking the Weird-Cmd via a script block ({ ... }), use redirection 6> to redirect the information stream to a temporary file:

try {
  Weird-Cmd 6>($tempFile = New-TemporaryFile)
  $inf = (Get-Content -ErrorAction Ignore -Raw $tempFile)
  $tempFile | Remove-Item -ErrorAction Ignore
  if ($inf) { throw $inf }
} catch {
  # ... handle the exception.
}

Note: If you simply want to relay the information-stream content as a non-terminating error, use the Write-Error cmdlet, either instead of throw with try / catch or from inside the catch block:

Write-Error $inf

zett42 points out that there's an in-memory alternative to 6>$someFile, namely to merge the information stream (6) into the success output stream (1) with 6>&1, and to filter out information-stream output objects by their type, System.Management.Automation.InformationRecord - this assumes that Weird-Cmd does not report a terminating error:

$inf = Weird-Cmd 6>&1 |
       Where-Object { $_ -is [System.Management.Automation.InformationRecord] }

That said, it would be nice to have a way to directly capture a specific stream's output in a variable rather than having to use a file, along the lines of: 6>variable:inf

This potential future enhancement is the subject of GitHub issue #4332.

  • Related