mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Make $ErrorActionPreference not affect stderr output of native commands (#13361)
This commit is contained in:
@@ -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' {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user