When using the parameter sets selected by -ErrorRecord / -Exception of Write-Error, it makes sense to bind (the first) positional argument of types (derived from) System.Management.Automation.ErrorRecord / System.Exception to those parameters.
Currently, that doesn't happen, because these parameters lack the Position=0 attribute field in their `Parameter attributes.
The result is that using something like Write-Error $_ in an apparent effort to pass the System.Management.Automation.ErrorRecord instance in $_ through, you end up with the equivalent of:
rather than the more sensible - and probably expected:
Write-Error -ErrorRecord $_
While the two resulting error records ultimately contain the same message (description), the specifics of the input error record are lost.
The same applies analogously to -Exception.
The fix is trivial: Add Position = 0 to the following two locations:
|
[Parameter(ParameterSetName = "ErrorRecord", Mandatory = true)] |
|
public ErrorRecord ErrorRecord { get; set; } = null; |
|
[Parameter(ParameterSetName = "WithException", Mandatory = true)] |
|
public Exception Exception { get; set; } = null; |
Steps to reproduce
Run the following tests:
# ErrorRecord
try { [int]::parse('foo') } catch {}; (Write-Error $Error[0] 2>&1).Exception.GetType().FullName | Should -Be System.Management.Automation.MethodInvocationException
# Exception
try { [int]::parse('foo') } catch {}; (Write-Error $Error[0].Exception.InnerException 2>&1).Exception.GetType().FullName | Should -Be System.FormatException
# Make sure that a string still binds to -Message.
try { [int]::parse('foo') } catch {}; (Write-Error "$($Error[0])" 2>&1).Exception.GetType().FullName | Should -Be Microsoft.PowerShell.Commands.WriteErrorException
Expected behavior
All tests should pass.
Actual behavior
The first two tests fail, because the positional arguments bind to -Message, resulting in a generic Microsoft.PowerShell.Commands.WriteErrorException exception wrapper.
Environment data
PowerShell Core 7.0.0-preview.4
When using the parameter sets selected by
-ErrorRecord/-ExceptionofWrite-Error, it makes sense to bind (the first) positional argument of types (derived from)System.Management.Automation.ErrorRecord/System.Exceptionto those parameters.Currently, that doesn't happen, because these parameters lack the
Position=0attribute field in their `Parameter attributes.The result is that using something like
Write-Error $_in an apparent effort to pass theSystem.Management.Automation.ErrorRecordinstance in$_through, you end up with the equivalent of:rather than the more sensible - and probably expected:
While the two resulting error records ultimately contain the same message (description), the specifics of the input error record are lost.
The same applies analogously to
-Exception.The fix is trivial: Add
Position = 0to the following two locations:PowerShell/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Write.cs
Lines 235 to 236 in d2c04f3
PowerShell/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Write.cs
Lines 217 to 218 in d2c04f3
Steps to reproduce
Run the following tests:
Expected behavior
All tests should pass.
Actual behavior
The first two tests fail, because the positional arguments bind to
-Message, resulting in a genericMicrosoft.PowerShell.Commands.WriteErrorExceptionexception wrapper.Environment data