|
| 1 | +--- |
| 2 | +RFC: Update $ErrorView with simplified views for Error Messages |
| 3 | +Author: Jason Helmick |
| 4 | +Status: Final |
| 5 | +Version: 1.0.0 |
| 6 | +Area: PowerShell |
| 7 | +Comments Due: 10/31/2019 |
| 8 | +--- |
| 9 | + |
| 10 | +# Update $ErrorView with simplified views for Error Messages |
| 11 | + |
| 12 | +When an error occurs in PowerShell, the customers on-screen error message experience currently |
| 13 | +provides a level of detail that obscures the exception message from being recognized and read by new |
| 14 | +or occasional PowerShell users. The addition of a simplified error view will improve both |
| 15 | +comprehension and troubleshooting experience. A new cmdlet `Get-Error` will provide |
| 16 | +complete detailed view of the fully qualified error when desired. |
| 17 | + |
| 18 | +## Motivation |
| 19 | + |
| 20 | +The on-screen experience, when receiving an error message, is controlled through the views |
| 21 | +NormalView (the default) and CategoryView. These are user selectable through the preference variable |
| 22 | +**$ErrorView**. This RFC describes Changing **$ErrorView** to an enumeration and adding one |
| 23 | +additional dynamic view to improve readability; 'ConciseView' |
| 24 | + |
| 25 | +- ConciseView - provides a concise error message suitable for new or occasional PowerShell users and |
| 26 | + a refactored view for advanced module builders. If the error is not from a script or parser error, |
| 27 | + then it's a single line error message. Otherwise, you get a multiline error message that contains |
| 28 | + the error, a pointer and error message showing where the error is in that line. If the terminal |
| 29 | + doesn't support Virtual Terminal, then vt100 color codes are not used. |
| 30 | + |
| 31 | +A comprehensive detailed view of the fully qualified error, including inner exceptions, will be |
| 32 | +provided by the `Get-Error` cmdlet. |
| 33 | + |
| 34 | +**$ErrorView** shall contain the original views for backward compatibility and to lessen this |
| 35 | +breaking change. The view list is as follows: |
| 36 | + |
| 37 | +- ConciseView |
| 38 | +- NormalView |
| 39 | +- CategoryView |
| 40 | + |
| 41 | +## Specification |
| 42 | + |
| 43 | +The proposal is to add one new view, 'ConciseView', to help improve error message comprehension. |
| 44 | +ConciseView will be the default view. For in-depth error object information, a new cmdlet |
| 45 | +'Get-Error' provides detailed error information. |
| 46 | + |
| 47 | +__Key Design Considerations__ |
| 48 | + |
| 49 | +1. To reduce confusion and improve debugging success for new and occasional users, error messages |
| 50 | + should call WriteErrorLine to produce a simplified message for interactive CLI users. |
| 51 | + |
| 52 | +- The error message will contain a prefix as described: |
| 53 | + |
| 54 | + - If the error is an Exception, it prefixes with Exception:. |
| 55 | + - If the error has InvocationInfo.MyCommand, it prefixes the command. |
| 56 | + - If the error has InvocationName, CategoryInfo.Category, or CategoryInfo.Reason, the message |
| 57 | + will prefix these. |
| 58 | + - Only if none of those exist does it actually use Error:. |
| 59 | + |
| 60 | +- Simplified error message syntax from 'Message'. (See below) |
| 61 | + |
| 62 | +```powershell |
| 63 | +PS C:\> Get-Childitem -Path c:\notreal |
| 64 | +Get-Childitem: Cannot find path ‘C:\notreal’ because it does not exist |
| 65 | +``` |
| 66 | + |
| 67 | +2. To improve script debugging for advanced module builders and scripters, a refactored error view |
| 68 | + will be displayed. If the error is not from a script or parser error, then it's a single line |
| 69 | + error message. Otherwise, you get a multiline error message that contains the error and a pointer |
| 70 | + and error message showing where the error is in that line. |
| 71 | + |
| 72 | +- A new property **ErrorAccentColor** is added to support changing the accent color of the error |
| 73 | + message. If the terminal doesn't support Virtual Terminal, then vt100 color codes are not used. |
| 74 | + |
| 75 | +```powershell |
| 76 | +PS C:\> .\MyScript.ps1 |
| 77 | +Get-ChildItem: C:\GitHub\MyScript.ps1 |
| 78 | +Line | |
| 79 | + 15 | Get-ChildItem -Path c:\NotReal |
| 80 | + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 81 | + | Cannot find path 'C:\NotReal' because it does not exist. |
| 82 | +``` |
| 83 | + |
| 84 | +- The error message is truncated and displayed by reusing the **MessagePosition** property of InvocationInfo |
| 85 | + |
| 86 | +```powershell |
| 87 | +PS C:\> .\MyScript.ps1 |
| 88 | +Selct-object: C:\GitHub\MyScript.ps1 |
| 89 | +Line | |
| 90 | + 25 | Get-Process | Selct-object -property NotReal |
| 91 | + | ~~~~~~~~~~~~ |
| 92 | + | The term 'Selct-object' is not recognized as the name of a cmdlet, function, script file, |
| 93 | + | or operable program. Check the spelling of the name, or if a path was included, |
| 94 | + | verify that the | path is correct and try again. |
| 95 | +``` |
| 96 | + |
| 97 | +3. A new cmdlet `Get-Error` will produce comprehensive detailed view of the fully qualified error, |
| 98 | + including nested inner exceptions. |
| 99 | + |
| 100 | +- Rendering is recursive for nested objects for Exceptions, InvocationInfo, and Arrays otherwise it |
| 101 | + uses ToString(). |
| 102 | +- Members that are empty or null are not shown. |
| 103 | +- Indentation uses 4 spaces for nested objects |
| 104 | +- A new FormatAccentColor is introduced to highlight property names from their values. This can be |
| 105 | + used later to add accents to tables and list formatting. |
| 106 | +- Removed some commented out unneeded code from ConciseView. |
| 107 | + |
| 108 | +- `Get-Error` will provide the following: |
| 109 | + |
| 110 | + - Display the newest Error ($Error[0]) – default behavior |
| 111 | + - Accept Pipeline input – support $error[1] | |
| 112 | + - Option for the Newest X errors in the session (This will be aliased with Last) |
| 113 | + |
| 114 | +- `Get-Error` syntax |
| 115 | + |
| 116 | +```powershell |
| 117 | +Get-Error [-InputObject <psobject>] [-Newest <Int32>] [-All] [<CommonParameters>] |
| 118 | +``` |
| 119 | + |
| 120 | +First parameter set |
| 121 | + |
| 122 | +- Newest |
| 123 | + |
| 124 | + + Datatype: int32 |
| 125 | + + specifies one or more of the newest errors to display |
| 126 | + + Not required |
| 127 | + |
| 128 | +__Example 1__ |
| 129 | +Error occurs in Interactive mode. Cmdlet displays details of the last error displayed |
| 130 | + |
| 131 | +```powershell |
| 132 | +PS C:\> Get-Childitem -Path c:\notreal |
| 133 | +Get-ChildItem: Cannot find path ‘C:\notreal’ because it does not exist |
| 134 | +
|
| 135 | +PS C:\test> Get-Error |
| 136 | +
|
| 137 | +**** Detailed message here **** |
| 138 | +``` |
| 139 | + |
| 140 | +__Example 2__ |
| 141 | +Error occurs in script, shows error from view 'Analytic', and then is piped |
| 142 | +from $error array to 'Get-Error' to display more details. |
| 143 | + |
| 144 | +```powershell |
| 145 | +PS C:\> .\MyScript.ps1 |
| 146 | +Selct-object: C:\GitHub\MyScript.ps1 |
| 147 | +Line | |
| 148 | + 25 | Get-Process | Selct-object -property NotReal |
| 149 | + | ~~~~~~~~~~~~ |
| 150 | + | The term 'Selct-object' is not recognized as the name of a cmdlet, function, script file, |
| 151 | + | or operable program. Check the spelling of the name, or if a path was included, |
| 152 | + | verify that the | path is correct and try again. |
| 153 | +
|
| 154 | +PS C:\> $error[0] | Get-Error |
| 155 | +
|
| 156 | +**** Detailed message here **** |
| 157 | +``` |
| 158 | + |
| 159 | +__Example 3__ |
| 160 | +Display detailed error information for the most recent 3 errors. |
| 161 | + |
| 162 | +```powershell |
| 163 | +PS C:\> Get-Error -Newest 3 |
| 164 | +
|
| 165 | +**** Detailed message here **** |
| 166 | +**** Detailed message here **** |
| 167 | +**** Detailed message here **** |
| 168 | +``` |
| 169 | + |
| 170 | +__Example 4__ |
| 171 | +Maintain the ErrorRecord object for additional pipeline operations |
| 172 | + |
| 173 | +```PowerShell |
| 174 | +PS C:\> Get-Error -Newest 3 | Select-String -Pattern 'MyFile.txt' |
| 175 | +
|
| 176 | +**** Detailed message here **** |
| 177 | +``` |
| 178 | + |
| 179 | +## Alternate Proposals and Considerations |
| 180 | + |
| 181 | +__Alternative/additional view customization__ |
| 182 | + |
| 183 | +It is conceivable in the future to add extensibility for module builders, |
| 184 | +that they could supply their own diagnostic script for specific error customization. |
| 185 | + |
| 186 | +__Alternative single-line display__ |
| 187 | + |
| 188 | +```powershell |
| 189 | +<CommandName>:<Exception Message> |
| 190 | +get-item: Cannot find path ‘C:\blah’ because it does not exist: |
| 191 | +
|
| 192 | +<CommandName>:<Exception Message>: <Position> |
| 193 | +get-item: Cannot find path ‘C:\blah’ because it does not exist: At line:1 char:1 |
| 194 | +
|
| 195 | +<CommandName>:<Alias>:<Exception Message>: <Position> |
| 196 | +get-item: gi: Cannot find path ‘C:\blah’ because it does not exist: At line:1 char:1 |
| 197 | +
|
| 198 | +ERROR:<Exception Message> |
| 199 | +ERROR: Cannot find path ‘C:\blah’ because it does not exist |
| 200 | +
|
| 201 | +ERROR:<Exception Message>: <Position> |
| 202 | +ERROR: Cannot find path ‘C:\blah’ because it does not exist: At line:1 char:1 |
| 203 | +
|
| 204 | +ERROR:<CommandName>:<Alias>:<Exception Message>: <Position> |
| 205 | +ERROR: get-item: gi: Cannot find path ‘C:\blah’ because it does not exist: At line:1 char:1 |
| 206 | +``` |
| 207 | + |
| 208 | +__Alternative color for all errors__ |
| 209 | + |
| 210 | +1. We could change the default error message color from the current RED foreground and BLACK background to ?. |
| 211 | +2. Differentiating errors based on termination condition: terminating versus non-terminating |
| 212 | +is currently not intuitive. We are examining differentiating these conditions on the console. |
| 213 | +Example, adding a new property $host.PrivateData.NonTerminatingErrorForegroundColor ='Red'. |
| 214 | +For occasional customers, all error messages remain as color Red. For advanced customers, |
| 215 | +they can change non-terminating errors to another color to separate the error |
| 216 | +termination type in the console. |
| 217 | + |
| 218 | +__Alternative For Error, Warning, Verbose__ |
| 219 | + |
| 220 | +1. We could be more terse in our messages and increase consistency with verbose |
| 221 | +and warning messages by using a single letter to identify the message. |
| 222 | + |
| 223 | +Legend: V = Verbose, W = Warning, E = Error(non-terminating future), F = Fatal |
| 224 | + |
| 225 | +```powershell |
| 226 | +V: You are running your code - what could possibly go wrong. |
| 227 | +
|
| 228 | +W: You are about to try something that probably will not work. |
| 229 | +
|
| 230 | +E: Your something broke, but Im still running. At line:1 char:1 |
| 231 | +
|
| 232 | +E: Your something broke, but Im still running. At line:1 char:1 |
| 233 | +
|
| 234 | +E: Your something broke, but Im still running. At line:1 char:1 |
| 235 | +
|
| 236 | +F: Now you really broke me. At line:1 char:1 |
| 237 | +
|
| 238 | +``` |
0 commit comments