Error Handling Improvements in PowerShell 7

PowerShell 7 has made some improvements in the way error handling and made it more useful. This includes changes in the default error view, new error action preference and introduction of new cmdlet, Get-Error as well.

Changes in the Error View

A new view called $ConciseView has been created to improve the readability of the errors. This generates a single line error. Before PowerShell 7, the default view used to be $NormalView, which used to generate multi-line error and enhanced view. We can view the current default by using variable $errorview:

# With PowerShell 7
PS /home/cloud_user> $errorview
ConciseView

# With PowerShell 5.1
PS C:\> $errorview
NormalView

We can view the available views in PowerShell 7 using [Enum]::getvalues([System.Management.Automation.ErrorView]):

PS /home/cloud_user> [Enum]::getvalues([System.Management.Automation.ErrorView])
NormalView
CategoryView
ConciseView

Let’s see the impact of setting these views on the error handling:

S /home/cloud_user> $ErrorView = 'CategoryView'
PS /home/cloud_user> Get-ChildItem -Path /etc/fakepath
ObjectNotFound: (/etc/fakepath:String) [Get-ChildItem], ItemNotFoundException
PS /home/cloud_user> 
PS /home/cloud_user> $ErrorView = 'NormalView'
PS /home/cloud_user> Get-ChildItem -Path /etc/fakepath
Get-ChildItem : Cannot find path '/etc/fakepath' because it does not exist.
At line:1 char:1
+ Get-ChildItem -Path /etc/fakepath
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (/etc/fakepath:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
PS /home/cloud_user> 
PS /home/cloud_user> $ErrorView = 'ConciseView'
PS /home/cloud_user> Get-ChildItem -Path /etc/fakepath
Get-ChildItem: Cannot find path '/etc/fakepath' because it does not exist.

A new property ErrorAccentColor is added to $Host.PrivateData to support changing the accent color of the error message. This can be used to adjust color for the error message.

New Cmdlet: Get-Error

A new cmdlet called Get-Error has been introduced in PowerShell 7 to catch all errors using cmdlet like functionality. By default it shows the last error. The information associated with error has also been improved upon and more details are available now:

PS /home/cloud_user> Get-Help Get-Error

NAME
    Get-Error
    
SYNTAX
    Get-Error [-Newest <int>] [<CommonParameters>]
    
    Get-Error [[-InputObject] <psobject>] [<CommonParameters>]
    

ALIASES
    gerr
    

REMARKS
    Get-Help cannot find the Help files for this cmdlet on this computer. It is displaying only partial help.
        -- To download and install Help files for the module that includes this cmdlet, use Update-Help.
        -- To view the Help topic for this cmdlet online, type: "Get-Help Get-Error -Online" or
           go to https://docs.microsoft.com/powershell/module/microsoft.powershell.utility/get-error.


PS /home/cloud_user> Get-Error         

Exception             : 
    Type                 : System.Management.Automation.ItemNotFoundException
    ErrorRecord          : 
        Exception             : 
            Type    : System.Management.Automation.ParentContainsErrorRecordException
            Message : Cannot find path '/etc/fakepath' because it does not exist.
            HResult : -2146233087
        TargetObject          : /etc/fakepath
        CategoryInfo          : ObjectNotFound: (/etc/fakepath:String) [], ParentContainsErrorRecordException
        FullyQualifiedErrorId : PathNotFound
    ItemName             : /etc/fakepath
    SessionStateCategory : Drive
    TargetSite           : 
        Name          : GetChildItems
        DeclaringType : System.Management.Automation.SessionStateInternal, System.Management.Automation, Version=7.1.3.0, Culture=neutral, PublicKeyToken=31bf
3856ad364e35
        MemberType    : Method
        Module        : System.Management.Automation.dll
    StackTrace           : 
   at System.Management.Automation.SessionStateInternal.GetChildItems(String path, Boolean recurse, UInt32 depth, CmdletProviderContext context) in /PowerShell/src/Sys
tem.Management.Automation/engine/SessionStateContainer.cs:line 1529
   at System.Management.Automation.ChildItemCmdletProviderIntrinsics.Get(String path, Boolean recurse, UInt32 depth, CmdletProviderContext context) in /PowerShell/src/
System.Management.Automation/engine/ChildrenCmdletProviderInterfaces.cs:line 278
   at Microsoft.PowerShell.Commands.GetChildItemCommand.ProcessRecord() in /PowerShell/src/Microsoft.PowerShell.Commands.Management/commands/management/GetChildrenComm
and.cs:line 318
    Message              : Cannot find path '/etc/fakepath' because it does not exist.
    Source               : System.Management.Automation
    HResult              : -2146233087
TargetObject          : /etc/fakepath
CategoryInfo          : ObjectNotFound: (/etc/fakepath:String) [Get-ChildItem], ItemNotFoundException
FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
InvocationInfo        : 
    MyCommand        : Get-ChildItem
    ScriptLineNumber : 1
    OffsetInLine     : 1
    HistoryId        : 8
    Line             : Get-ChildItem -Path /etc/fakepath
    PositionMessage  : At line:1 char:1
                       + Get-ChildItem -Path /etc/fakepath
                       + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    InvocationName   : Get-ChildItem
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : 

As you can note that exception type in above message is System.Management.Automation.ItemNotFoundException, so allows you to code for these specific types as well now.

A somewhat limited capability is available using $Error array in previous versions and you have to iterate through it to get errors:

PS C:\> $Error[0]
get-childitem : Der Pfad "C:\fakepath" kann nicht gefunden werden, da er nicht vorhanden ist.
In Zeile:1 Zeichen:1
+ get-childitem -path fakepath
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\fakepath:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

PS C:\> $Error[1]
get-error : Die Benennung "get-error" wurde nicht als Name eines Cmdlet, einer Funktion, einer Skriptdatei oder eines ausführbaren Programms erkannt. Überprüfen Sie die Schreibweise des
Namens, oder ob der Pfad korrekt ist (sofern enthalten), und wiederholen Sie den Vorgang.
In Zeile:1 Zeichen:1
+ get-error
+ ~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (get-error:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

The Get-Error cmdlet also supports input from the pipeline using the built-in variable $Error. In such scenario, Get-Error displays all piped errors.

New Error Action Preference as Break

A new ErrorActionPreference Break was added in PowerShell 7. This allows you to enter the debugger when an error occurs or when an exception is raised. By default, its set to Continue in PowerShell 7 or previous versions. You can view the current action preference by using $ErrorActionPreference:

# With PowerShell 7
PS /home/cloud_user> $ErrorActionPreference
Continue
PS /home/cloud_user> $ErrorActionPreference = 'Break'
PS /home/cloud_user> 
PS /home/cloud_user> Get-ChildItem -Path /etc/fakepath
Entering debug mode. Use h or ? for help. 

At line:1 char:1
+ Get-ChildItem -Path /etc/fakepath
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[DBG]: PS /home/cloud_user>> 

# With PowerShell 5.1
PS C:\> $ErrorActionPreference
Continue
PS C:\> $ErrorActionPreference = 'Break'
Der Wert "Break" kann nicht in den Typ "System.Management.Automation.ActionPreference" konvertiert werden. Fehler: "Der Bezeichner "Break" kann keinem gültigen Enumeratornamen zugeordnet
werden. Geben Sie einen der folgenden Enumeratornamen an, und wiederholen Sie den Vorgang:
SilentlyContinue, Stop, Continue, Inquire, Ignore, Suspend"
In Zeile:1 Zeichen:1
+ $ErrorActionPreference = 'Break'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
    + FullyQualifiedErrorId : RuntimeException

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s