Make $ErrorActionPreference not affect stderr output of native commands (#13361)

This commit is contained in:
Steve Lee
2020-08-07 14:19:17 -07:00
committed by GitHub
parent fe2019b054
commit 511858a267
6 changed files with 61 additions and 64 deletions
@@ -123,6 +123,9 @@ namespace System.Management.Automation
new ExperimentalFeature(
name: "PSNativePSPathResolution",
description: "Convert PSPath to filesystem path, if possible, for native commands"),
new ExperimentalFeature(
name: "PSNotApplyErrorActionToStderr",
description: "Don't have $ErrorActionPreference affect stderr output"),
};
EngineExperimentalFeatures = new ReadOnlyCollection<ExperimentalFeature>(engineFeatures);
@@ -2831,61 +2831,62 @@ namespace System.Management.Automation
this.PipelineProcessor.LogExecutionError(_thisCommand.MyInvocation, errorRecord);
}
ActionPreference preference = ErrorAction;
if (actionPreference.HasValue)
if (!(ExperimentalFeature.IsEnabled("PSNotApplyErrorActionToStderr") && isNativeError))
{
preference = actionPreference.Value;
}
ActionPreference preference = ErrorAction;
if (actionPreference.HasValue)
{
preference = actionPreference.Value;
}
// No trace of the error in the 'Ignore' case
if (ActionPreference.Ignore == preference)
{
return; // do not write or record to output pipe
}
// No trace of the error in the 'Ignore' case
if (ActionPreference.Ignore == preference)
{
return; // do not write or record to output pipe
}
// 2004/05/26-JonN
// The object is not written in the SilentlyContinue case
if (ActionPreference.SilentlyContinue == preference)
{
AppendErrorToVariables(errorRecord);
return; // do not write to output pipe
}
if (ContinueStatus.YesToAll == lastErrorContinueStatus)
{
preference = ActionPreference.Continue;
}
switch (preference)
{
case ActionPreference.Stop:
ActionPreferenceStopException e =
new ActionPreferenceStopException(
MyInvocation,
errorRecord,
StringUtil.Format(CommandBaseStrings.ErrorPreferenceStop,
"ErrorActionPreference",
errorRecord.ToString()));
throw ManageException(e);
case ActionPreference.Inquire:
// ignore return value
// this will throw if the user chooses not to continue
lastErrorContinueStatus = InquireHelper(
RuntimeException.RetrieveMessage(errorRecord),
null,
true, // allowYesToAll
false, // allowNoToAll
true, // replaceNoWithHalt
false // hasSecurityImpact
);
break;
}
// 2004/05/26-JonN
// The object is not written in the SilentlyContinue case
if (ActionPreference.SilentlyContinue == preference)
{
AppendErrorToVariables(errorRecord);
return; // do not write to output pipe
}
if (ContinueStatus.YesToAll == lastErrorContinueStatus)
{
preference = ActionPreference.Continue;
}
switch (preference)
{
case ActionPreference.Stop:
ActionPreferenceStopException e =
new ActionPreferenceStopException(
MyInvocation,
errorRecord,
StringUtil.Format(CommandBaseStrings.ErrorPreferenceStop,
"ErrorActionPreference",
errorRecord.ToString()));
throw ManageException(e);
case ActionPreference.Inquire:
// ignore return value
// this will throw if the user chooses not to continue
lastErrorContinueStatus = InquireHelper(
RuntimeException.RetrieveMessage(errorRecord),
null,
true, // allowYesToAll
false, // allowNoToAll
true, // replaceNoWithHalt
false // hasSecurityImpact
);
break;
}
// 2005/01/20 Do not write the object to $error if
// ManageException has already done so
AppendErrorToVariables(errorRecord);
// Add this note property and set its value to true for F&O
// to decide whether to call WriteErrorLine or WriteLine.
// We want errors to print in red in both cases.
@@ -100,19 +100,6 @@ Describe "ConsoleHost unit tests" -tags "Feature" {
{ & $powershell -outp blah -comm { $input } } | Should -Throw -ErrorId "IncorrectValueForFormatParameter"
}
It "Verify Validate Dollar Error Populated should throw exception" {
$origEA = $ErrorActionPreference
$ErrorActionPreference = "Stop"
$a = 1,2,3
$e = {
$a | & $powershell -noprofile -command { wgwg-wrwrhqwrhrh35h3h3}
} | Should -Throw -ErrorId "CommandNotFoundException" -PassThru
$e.ToString() | Should -Match "wgwg-wrwrhqwrhrh35h3h3"
$ErrorActionPreference = $origEA
}
It "Verify Validate Output Format As Text Explicitly Child Single Shell does not throw" {
{
"blahblah" | & $powershell -noprofile -out text -com { $input }
@@ -140,6 +140,10 @@ Describe "Native Command Processor" -tags "Feature" {
[Console]::OutputEncoding = $originalOutputEncoding
}
}
It '$ErrorActionPreference does not apply to redirected stderr output' -Skip:(!$EnabledExperimentalFeatures.Contains('PSNotApplyErrorActionToStderr')) {
pwsh -noprofile -command '$ErrorActionPreference = ''Stop''; testexe -stderr stop 2>$null; ''hello''; $error' | Should -BeExactly 'hello'
}
}
Describe "Open a text file with NativeCommandProcessor" -tags @("Feature", "RequireAdminOnWindows") {
@@ -21,8 +21,7 @@ Describe "Native streams behavior with PowerShell" -Tags 'CI' {
# this check should be the first one, because $error is a global shared variable
It 'should not add records to $error variable' {
# we are keeping existing Windows PS v5.1 behavior for $error variable
$error.Count | Should -Be 9
$error.Count | Should -Be 0
}
It 'uses ErrorRecord object to return stderr output' {
+3
View File
@@ -24,6 +24,9 @@ namespace TestExe
// Used to test functionality depending on $LASTEXITCODE, like &&/|| operators
Console.WriteLine(args[1]);
return int.Parse(args[1]);
case "-stderr":
Console.Error.WriteLine(args[1]);
break;
default:
Console.WriteLine("Unknown test {0}", args[0]);
break;