Understanding the PowerShell 7 Error Variable

PowerShell

As with any programming language, code will have errors and troubleshooting those problems can be difficult. Thankfully, PowerShell has a rich error object and several powerful tools to help debug your code.

With PowerShell 7, these tools become even more useful and error handling even easier. As the language evolves and becomes used in more places than ever, being able to quickly and efficiently troubleshoot a problem will prove invaluable to integrating the language into common workflows.

Understanding Errors in PowerShell

Broadly speaking, PowerShell errors fall into two categories, terminating and non-terminating. Though these concepts are worth articles in their own right, a terminating error implies that code execution is stopped when the error is thrown. A non-terminating error implies that the code will continue despite an error message being shown.

Terminating Errors

As you can see below, the text “This should never be shown”, is not shown, as the terminating error stops code execution. The function throw will always return a terminating error.

Untitled 41
Figure 1 – Terminating Error Output

Non-Terminating Errors

It is more difficult to arbitrarily generate a non-terminating error, but one easy way is to use the Get-ChildItem cmdlet and ask the cmdlet to find a nonexistent directory. As you can tell the command Write-Host "This text will show!", does in fact appear.

Untitled 42
Figure 2 – Non-Terminating Error Output

You can turn most non-terminating errors into terminating errors by modifying an individual cmdlet’s ErrorAction to Stop. For example, Get-ChildItem "missing_dir" -ErrorAction 'Stop'

Error Views

You might notice that in the previous output, there are two different views of the error information. Figure 1 shows the NormalView of the $ErrorView preference variable. This view was standard and traditional until PowerShell 7. Starting with PowerShell 7, the default view has changed to what you see in Figure 2 and that is of the ConciseView. It dispenses with much of the decoration around the output, but as you might be able to tell, some information is not made available.

The Error Object Behind the Scenes

Underlying the data behind the error output is the $Error object that is populated by PowerShell when errors are thrown. To view this data, you are able to output and walk through the information. The traditional way to get the last error thrown is by calling $Error[0]. This uses array notation to reference the error.

Untitled 43
Figure 4 – $Error Object

If you happen to mistype this command, you will overwrite the first object in the error collection with the new error, so be careful when referencing this object.

As you can see there is the same error as originally shown, but we want to view more of the data. By selecting all of the properties, we are able to see what’s available. As we will talk about in the next section, the Get-Error cmdlet provides a rich view of this data, but it’s important to understand what is going on underneath.

Untitled 44
Figure 5 – Error Object Properties

By walking through each property we can see what information exists between the Get-Error cmdlet and the $Error object itself.

Untitled 45
Figure 6 – Error Object Exception Properties

The New Get-Error Cmdlet

That brings us to the next PowerShell 7 addition and that is the Get-Error cmdlet. To expand upon the ConciseView and show far more detail, we can run the Get-Error cmdlet and see the expanded details of the last error thrown.

Related article: Error Handling With PowerShell Try Catch Blocks

Untitled 46
Figure 3 – Get-Error Output

There is a lot of information shown here, so let’s break down what is useful.

Exception

  • Type – Basic Exception Information
  • ErrorRecordMost of this information is from the $Error object itself. The TargetObject, CategoryInfo, and FullyQualifiedErrorId are all duplicated further in the Get-Error output. What is useful is the Exception data.
    • Type – An exception, but could be referencing the parent exception
    • Message – The human-readable error message
    • HResult – Traditional numerical error code that Windows has used since the early days of the operating system
  • ItemName – The same as the TargetObject shown later in the Get-Error output
  • SessionStateCategory A series of values that errors fall into, this is an enum underneath
  • TargetSite – A set of information that exposes some of the internal PowerShell engine values and where the error itself is coming from
  • StackTrace – This is the actual method signature of where the error itself came from and can help aid in why an error was shown
  • Message – The human-readable error message
  • Source – This is the source of where the error is coming from
  • HResult – As discussed above, the traditional numerical error code from Windows

TargetObject

The object that the function, cmdlet, or code targets, in this case D:\\missing_dir

CategoryInfo

A concatenated view of several different properties, breaking down to the below format:

<Error>: (<TargetObject>:<ObjectType>) [<Originating CmdLet>], <Exception Type>

FullyQualifiedErrorId

The FullyQualifiedErrorId is Message property of the exception object combined with the fully-qualified name of the class where the exception originated.

InvocationInfo

  • MyCommand – The originating cmdlet or function throwing the error
  • ScriptLineNumber – Location within the file or ScriptBlock that the error is thrown
  • OffsetInLine – The location within the line that the error was thrown
  • HistoryId – The location from within the Get-History cmdlet that the error was thrown
  • Line – The command throwing the error
  • PositionMessage – Combined information for the error
  • InvocationName – The cmdlet or function throwing the error
  • CommandOrigin – In what context the error was thrown

ScriptStackTrace

Contained here is information on where in a script the error occurred. In this case, the error occurred on line 1, but this will reflect the line of the error in the given ScriptBlock.

Conclusion

Unlike other programming languages, PowerShell provides a very rich error object to figure out what went wrong and help to debug troublesome code. With PowerShell 7, the ability to decipher errors is even easier with the introduction of the Get-Error cmdlet. Furthermore, the ConciseView of the ErrorAction preference will keep the command line free from clutter and make coding even easier!