PowerShell / PowerShell

PowerShell for every system!
https://microsoft.com/PowerShell
MIT License
43.55k stars 7.06k forks source link

Tee object can now store received error records to a variable. #21565

Open JamesWTruher opened 2 weeks ago

JamesWTruher commented 2 weeks ago

This addresses an aspect of issue #5184

PR Summary

This adds the parameter -ErrorRecordVariable (Alias ERV) to Tee-Object if Tee-Object receives an ErrorRecord in the input stream and -ErrorRecordVariable is included, Tee-Object will assign those error records to the variable. This enables the following scenario:

PS> Get-Item $PSHOME,doesnotexist 2>&1 | Tee-Object -var out -ERV ee

    Directory: /Users/james/src/github/forks/jameswtruher/PowerShell-1/src/powershell-unix/bin/Debug/net9.0/osx-x64

UnixMode         User Group         LastWriteTime         Size Name
--------         ---- -----         -------------         ---- ----
drwxr-xr-x      james staff        5/1/2024 11:34         9024 publish

PS> $out

    Directory: /Users/james/src/github/forks/jameswtruher/PowerShell-1/src/powershell-unix/bin/Debug/net9.0/osx-x64

UnixMode         User Group         LastWriteTime         Size Name
--------         ---- -----         -------------         ---- ----
drwxr-xr-x      james staff        5/1/2024 11:34         9024 publish

PS> $ee
Get-Item: Cannot find path '/Users/james/src/github/forks/jameswtruher/PowerShell-1/src/Microsoft.PowerShell.Commands.Utility/commands/utility/doesnotexist' because it does not exist.
PS>

It works with file, literalfile, and variable parameter sets. This works with native executables as well, as when stderr is written, we create an error record. Errors created by Tee-Object are emitted in the normal way, it is only the input object which is inspected and handled by this new behavior. Note: the 2>&1 is required to ensure that the error stream is emitted into the output stream

PR Context

PR Checklist

Jaykul commented 2 weeks ago

From the example, you seem to have eaten the error!?

Tee-Object should still pass through errors, surely.

Jaykul commented 2 weeks ago

Incidentally, is it even possible to get output in -OutVariable or -ErrorVariable from this command?

I mean, even when I do, say | Tee-Object -File Variable:\Foo or | Tee -File NoSuchDrive:\log.txt I do not get an error.

It's weird to me that it has two parameters for output and error variables, but the one we all EXPECT ... does not work. It's pretty confusing.

SteveL-MSFT commented 1 week ago

Incidentally, is it even possible to get output in -OutVariable or -ErrorVariable from this command?

I mean, even when I do, say | Tee-Object -File Variable:\Foo or | Tee -File NoSuchDrive:\log.txt I do not get an error.

It's weird to me that it has two parameters for output and error variables, but the one we all EXPECT ... does not work. It's pretty confusing.

If you redirect stderr to stdout and pipe to Tee-Object, you'll get both into the output stream and can do whatever you want. We thought the ask was to be able to handle stderr separately thus the new variable to de-multiplex it. Certainly you could do this yourself just by looking at the type of object and this was a convenience feature.

mklement0 commented 1 day ago

@SteveL-MSFT, while I can appreciate what this PR is trying to achieve, I think it is ultimately the wrong way to go about it, especially given that it requires modifying the call that provides the input (2>&1) in order to work meaningfully.