Skip to content

Latest commit

 

History

History
238 lines (172 loc) · 8.72 KB

RFC0048-Update-Error-View.md

File metadata and controls

238 lines (172 loc) · 8.72 KB
RFC Author Status Version Area Comments Due
Update $ErrorView with simplified views for Error Messages
Jason Helmick
Final
1.0.0
PowerShell
10/31/2019

Update $ErrorView with simplified views for Error Messages

When an error occurs in PowerShell, the customers on-screen error message experience currently provides a level of detail that obscures the exception message from being recognized and read by new or occasional PowerShell users. The addition of a simplified error view will improve both comprehension and troubleshooting experience. A new cmdlet Get-Error will provide complete detailed view of the fully qualified error when desired.

Motivation

The on-screen experience, when receiving an error message, is controlled through the views NormalView (the default) and CategoryView. These are user selectable through the preference variable $ErrorView. This RFC describes Changing $ErrorView to an enumeration and adding one additional dynamic view to improve readability; 'ConciseView'

  • ConciseView - provides a concise error message suitable for new or occasional PowerShell users and a refactored view for advanced module builders. If the error is not from a script or parser error, then it's a single line error message. Otherwise, you get a multiline error message that contains the error, a pointer and error message showing where the error is in that line. If the terminal doesn't support Virtual Terminal, then vt100 color codes are not used.

A comprehensive detailed view of the fully qualified error, including inner exceptions, will be provided by the Get-Error cmdlet.

$ErrorView shall contain the original views for backward compatibility and to lessen this breaking change. The view list is as follows:

  • ConciseView
  • NormalView
  • CategoryView

Specification

The proposal is to add one new view, 'ConciseView', to help improve error message comprehension. ConciseView will be the default view. For in-depth error object information, a new cmdlet 'Get-Error' provides detailed error information.

Key Design Considerations

  1. To reduce confusion and improve debugging success for new and occasional users, error messages should call WriteErrorLine to produce a simplified message for interactive CLI users.
  • The error message will contain a prefix as described:

    • If the error is an Exception, it prefixes with Exception:.
    • If the error has InvocationInfo.MyCommand, it prefixes the command.
    • If the error has InvocationName, CategoryInfo.Category, or CategoryInfo.Reason, the message will prefix these.
    • Only if none of those exist does it actually use Error:.
  • Simplified error message syntax from 'Message'. (See below)

PS C:\> Get-Childitem -Path c:\notreal
Get-Childitem: Cannot find path C:\notreal because it does not exist
  1. To improve script debugging for advanced module builders and scripters, a refactored error view will be displayed. If the error is not from a script or parser error, then it's a single line error message. Otherwise, you get a multiline error message that contains the error and a pointer and error message showing where the error is in that line.
  • A new property ErrorAccentColor is added to support changing the accent color of the error message. If the terminal doesn't support Virtual Terminal, then vt100 color codes are not used.
PS C:\> .\MyScript.ps1
Get-ChildItem: C:\GitHub\MyScript.ps1
Line |
  15 | Get-ChildItem -Path c:\NotReal
     | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Cannot find path 'C:\NotReal' because it does not exist.
  • The error message is truncated and displayed by reusing the MessagePosition property of InvocationInfo
PS C:\> .\MyScript.ps1
Selct-object: C:\GitHub\MyScript.ps1
Line |
  25 | Get-Process | Selct-object -property NotReal
     |               ~~~~~~~~~~~~
     | The term 'Selct-object' is not recognized as the name of a cmdlet, function, script file,
     | or operable program. Check the spelling of the name, or if a path was included,
     | verify that the | path is correct and try again.
  1. A new cmdlet Get-Error will produce comprehensive detailed view of the fully qualified error, including nested inner exceptions.
  • Rendering is recursive for nested objects for Exceptions, InvocationInfo, and Arrays otherwise it uses ToString().

  • Members that are empty or null are not shown.

  • Indentation uses 4 spaces for nested objects

  • A new FormatAccentColor is introduced to highlight property names from their values. This can be used later to add accents to tables and list formatting.

  • Removed some commented out unneeded code from ConciseView.

  • Get-Error will provide the following:

    • Display the newest Error ($Error[0]) – default behavior
    • Accept Pipeline input – support $error[1] |
    • Option for the Newest X errors in the session (This will be aliased with Last)
  • Get-Error syntax

Get-Error  [-InputObject <psobject>] [-Newest <Int32>] [-All] [<CommonParameters>]

First parameter set

  • Newest

    • Datatype: int32
    • specifies one or more of the newest errors to display
    • Not required

Example 1 Error occurs in Interactive mode. Cmdlet displays details of the last error displayed

PS C:\> Get-Childitem -Path c:\notreal
Get-ChildItem: Cannot find path C:\notreal because it does not exist

PS C:\test> Get-Error

**** Detailed message here ****

Example 2 Error occurs in script, shows error from view 'Analytic', and then is piped from $error array to 'Get-Error' to display more details.

PS C:\> .\MyScript.ps1
Selct-object: C:\GitHub\MyScript.ps1
Line |
  25 | Get-Process | Selct-object -property NotReal
     |               ~~~~~~~~~~~~
     | The term 'Selct-object' is not recognized as the name of a cmdlet, function, script file,
     | or operable program. Check the spelling of the name, or if a path was included,
     | verify that the | path is correct and try again.

PS C:\> $error[0] | Get-Error

**** Detailed message here ****

Example 3 Display detailed error information for the most recent 3 errors.

PS C:\> Get-Error -Newest 3

**** Detailed message here ****
**** Detailed message here ****
**** Detailed message here ****

Example 4 Maintain the ErrorRecord object for additional pipeline operations

PS C:\> Get-Error -Newest 3 | Select-String -Pattern 'MyFile.txt'

**** Detailed message here ****

Alternate Proposals and Considerations

Alternative/additional view customization

It is conceivable in the future to add extensibility for module builders, that they could supply their own diagnostic script for specific error customization.

Alternative single-line display

<CommandName>:<Exception Message>
get-item: Cannot find path C:\blah because it does not exist:

<CommandName>:<Exception Message>: <Position>
get-item: Cannot find path C:\blah because it does not exist: At line:1 char:1

<CommandName>:<Alias>:<Exception Message>: <Position>
get-item: gi: Cannot find path C:\blah because it does not exist: At line:1 char:1

ERROR:<Exception Message>
ERROR: Cannot find path C:\blah because it does not exist

ERROR:<Exception Message>: <Position>
ERROR: Cannot find path C:\blah because it does not exist: At line:1 char:1

ERROR:<CommandName>:<Alias>:<Exception Message>: <Position>
ERROR: get-item: gi: Cannot find path C:\blah because it does not exist: At line:1 char:1

Alternative color for all errors

  1. We could change the default error message color from the current RED foreground and BLACK background to ?.
  2. Differentiating errors based on termination condition: terminating versus non-terminating is currently not intuitive. We are examining differentiating these conditions on the console. Example, adding a new property $host.PrivateData.NonTerminatingErrorForegroundColor ='Red'. For occasional customers, all error messages remain as color Red. For advanced customers, they can change non-terminating errors to another color to separate the error termination type in the console.

Alternative For Error, Warning, Verbose

  1. We could be more terse in our messages and increase consistency with verbose and warning messages by using a single letter to identify the message.

Legend: V = Verbose, W = Warning, E = Error(non-terminating future), F = Fatal

V: You are running your code - what could possibly go wrong.

W: You are about to try something that probably will not work.

E: Your something broke, but Im still running. At line:1 char:1

E: Your something broke, but Im still running. At line:1 char:1

E: Your something broke, but Im still running. At line:1 char:1

F: Now you really broke me. At line:1 char:1