Let's take this script:
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
try
{
echo "ErrorActionPreference = $ErrorActionPreference"
Copy-Item "this_is_a_bad_path"
Write-Host "Did not catch error"
}
catch
{
Write-Host "Caught Error"
}
This works as expected with this output:
ErrorActionPreference = Stop
Caught Error
But if I add -verbose
to the line, giving me Copy-Item -verbose "this_is_a_bad_path"
, the $ErrorActionPrefrence
is no longer used and I get this output:
ErrorActionPreference = Stop
Copy-Item : Cannot find path 'C:\Users\porter.bassett\this_is_a_bad_path' because it does not exist.
At C:\Users\porter.bassett\dot.ps1:7 char:3
+ Copy-Item -verbose "this_is_a_bad_path"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Users\porter...s_is_a_bad_path:String) [Copy-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand
Did not catch error
In order to get it to work properly with -verbose
turned, on, I have to add -ErrorAction Stop
to the line giving me Copy-Item -verbose "this_is_a_bad_path" -ErrorAction Stop
Why can't I rely on $ErrorActionPreference
when using -Verbose
?
$ErrorActionPreference. Determines how PowerShell responds to a non-terminating error, an error that doesn't stop the cmdlet processing. For example, at the command line or in a script, cmdlet, or provider, such as the errors generated by the Write-Error cmdlet.
The default value of $ErrorActionPreference is Continue. When that is the setting, the appearance when running ForLoop. ps1 is the same as that shown in Figure 17-1.
-ErrorAction:SilentlyContinue suppresses the error message and continues executing the command. -ErrorAction:Stop displays the error message and stops executing the command.
Using Stop with ErrorAction The stop option as the name suggests stops the command from execution after encountering an error. The following command shows the implementation of the Stop option with ErrorAction. > Write-Error "Error encountered" -ErrorAction Stop ; Write-Host "execution continued!!"
This is a feature/bug in PowerShell as also discussed on Technet here: Verbose common parameter disables ErrorActionPreference.
This feature/bug is there in PowerShell 4 and the latest version 5 as well.
Well, I don't have a why, but this triple face palm issue (well, at least IMHO), is still active in the open source PS code:
https://github.com/PowerShell/PowerShell/blob/02b5f357a20e6dee9f8e60e3adb9025be3c94490/src/System.Management.Automation/engine/MshCommandRuntime.cs#L3207 :
/// <summary>
/// ErrorAction tells the command what to do when an error occurs
/// </summary>
/// <exception cref="System.Management.Automation.ExtendedTypeSystemException">
/// (get-only) An error occurred accessing $ErrorAction.
/// </exception>
/// <remarks>
/// This is a common parameter via class CommonParameters.
/// </remarks>
internal ActionPreference ErrorAction
{
get
{
// Setting CommonParameters.ErrorAction has highest priority
if (IsErrorActionSet)
return _errorAction;
// Debug takes preference over Verbose
if (Debug)
return ActionPreference.Inquire;
if (Verbose)
return ActionPreference.Continue; *** WTF!?! ***
// fall back to $ErrorAction
if (!_isErrorActionPreferenceCached)
{
bool defaultUsed = false;
_errorAction = Context.GetEnumPreference<ActionPreference>(SpecialVariables.ErrorActionPreferenceVarPath, _errorAction, out defaultUsed);
_isErrorActionPreferenceCached = true;
}
return _errorAction;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With