This is a follow up to my last question and just a request for clarification.
Because ThrowTerminatingError()
will terminate the cmdlet as well as stop processing the items in a pipeline. What is the correct way to deal with 'problem' objects in a pipeline but you still want to continue processing the remaining items?
I'll use a very trivial example here, consider this function:
Function Do-Something
{
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True,
ValueFromPipeline=$True)]
[int]$value
)
process
{
if($value -eq 3)
{
// Terminate if $value is 3.
}
Write-Output($value)
}
}
Now assume this function is being invoked like so...
1..10 | Do-Something
Using throw
:
if($value -eq 3)
{
throw '$value was 3'
}
This is the output:
1
2
$value was 3
At C:\Users\Me\Desktop\Untitled1.ps1:51 char:12
+ throw '$value was 3'
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: ($value was 3:String) [], RuntimeException
+ FullyQualifiedErrorId : $value was 3
Using ThrowTerminatingError()
:
if($value -eq 3)
{
$PSCmdlet.ThrowTerminatingError((New-Object System.Management.Automation.ErrorRecord -ArgumentList (new-object System.Exception -ArgumentList ('$value was 3')), 'ValueWas3', 'NotSpecified', $value))
}
Generates similar output:
1
2
Do-Something : $value was 3
At C:\Users\Me\Desktop\Untitled1.ps1:57 char:9
+ 1..10 | Do-Something
+ ~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (3:Int32) [Do-Something], Exception
+ FullyQualifiedErrorId : ValueWas3,Do-Something
However if I use Write-Error and a return statement:
if($value -eq 3)
{
Write-Error((New-Object System.Management.Automation.ErrorRecord -ArgumentList (new-object System.Exception -ArgumentList ('$value was 3')), 'ValueWas3', 'NotSpecified', $value))
return
}
The items all process, reporting an error on the third one:
1
2
Do-Something : $value was 3
At C:\Users\Me\Desktop\Untitled1.ps1:58 char:9
+ 1..10 | Do-Something
+ ~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
,Do-Something
4
5
6
7
8
9
10
Is this the correct way I should be dealing with problems with pipelined objects, or should I be looking at the structure of my functions?
Basically, I just want to know how should I deal with an object in a pipeline that can't be processed, but I want to continue to process any remaining ones.
The reason I'd want something like this is in the end
block of a function I may sometimes want to report on which items were successfully processed and which failed (possibly with a reason).