PortMan
PortMan

Reputation: 4523

Why does -Verbose disable the use of $ErrorActionPreference?

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?

Upvotes: 9

Views: 621

Answers (3)

Max
Max

Reputation: 77

Your best bet is to specify erroraction for every command in your module.

write-host foo -ErrorAction Stop

Updated: this blog post is helpful. It explains how global var inheritance causes the observed behavior.

https://blogs.technet.microsoft.com/heyscriptingguy/2014/04/26/weekend-scripter-access-powershell-preference-variables/

Upvotes: -2

Martin Ba
Martin Ba

Reputation: 38891

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;
        }

Upvotes: 2

Aman Sharma
Aman Sharma

Reputation: 1990

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.

Upvotes: 2

Related Questions