1
+ <#
2
+ if (@('NativeCommandErrorMessage','NativeCommandError') -notcontains $_.FullyQualifiedErrorId -and @('CategoryView','ConciseView','DetailedView') -notcontains $ErrorView)
3
+ {
4
+ $myinv = $_.InvocationInfo
5
+ if ($myinv -and $myinv.MyCommand)
6
+ {
7
+ switch -regex ( $myinv.MyCommand.CommandType )
8
+ {
9
+ ([System.Management.Automation.CommandTypes]::ExternalScript)
10
+ {
11
+ if ($myinv.MyCommand.Path)
12
+ {
13
+ $myinv.MyCommand.Path + ' : '
14
+ }
15
+
16
+ break
17
+ }
18
+
19
+ ([System.Management.Automation.CommandTypes]::Script)
20
+ {
21
+ if ($myinv.MyCommand.ScriptBlock)
22
+ {
23
+ $myinv.MyCommand.ScriptBlock.ToString() + ' : '
24
+ }
25
+
26
+ break
27
+ }
28
+ default
29
+ {
30
+ if ($myinv.InvocationName -match '^[&\.]?$')
31
+ {
32
+ if ($myinv.MyCommand.Name)
33
+ {
34
+ $myinv.MyCommand.Name + ' : '
35
+ }
36
+ }
37
+ else
38
+ {
39
+ $myinv.InvocationName + ' : '
40
+ }
41
+
42
+ break
43
+ }
44
+ }
45
+ }
46
+ elseif ($myinv -and $myinv.InvocationName)
47
+ {
48
+ $myinv.InvocationName + ' : '
49
+ }
50
+ }
51
+
52
+
53
+ Set-StrictMode -Off
54
+ $ErrorActionPreference = 'Stop'
55
+ trap { 'Error found in error view definition: ' + $_.Exception.Message }
56
+ $newline = [Environment]::Newline
57
+
58
+ $resetColor = ''
59
+ $errorColor = ''
60
+ $accentColor = ''
61
+
62
+ if ($Host.UI.SupportsVirtualTerminal -and ([string]::IsNullOrEmpty($env:__SuppressAnsiEscapeSequences))) {
63
+ $resetColor = $PSStyle.Reset
64
+ $errorColor = $PSStyle.Formatting.Error
65
+ $accentColor = $PSStyle.Formatting.ErrorAccent
66
+ }
67
+ function Get-ConciseViewPositionMessage {
68
+
69
+ # returns a string cut to last whitespace
70
+ function Get-TruncatedString($string, [int]$length) {
71
+
72
+ if ($string.Length -le $length) {
73
+ return $string
74
+ }
75
+
76
+ return ($string.Substring(0,$length) -split '\s',-2)[0]
77
+ }
78
+
79
+ $posmsg = ''
80
+ $headerWhitespace = ''
81
+ $offsetWhitespace = ''
82
+ $message = ''
83
+ $prefix = ''
84
+
85
+ # The checks here determine if we show line detailed error information:
86
+ # - check if `ParserError` and comes from PowerShell which eventually results in a ParseException, but during this execution it's an ErrorRecord
87
+ # - check if invocation is a script or multiple lines in the console
88
+ # - check that it's not a script module as expectation is that users don't want to see the line of error within a module
89
+ if ((($err.CategoryInfo.Category -eq 'ParserError' -and $err.Exception -is 'System.Management.Automation.ParentContainsErrorRecordException') -or $myinv.ScriptName -or $myinv.ScriptLineNumber -gt 1) -and $myinv.ScriptName -notmatch '\.psm1$') {
90
+ $useTargetObject = $false
91
+
92
+ # Handle case where there is a TargetObject and we can show the error at the target rather than the script source
93
+ if ($_.TargetObject.Line -and $_.TargetObject.LineText) {
94
+ $posmsg = "${resetcolor}$($_.TargetObject.File)${newline}"
95
+ $useTargetObject = $true
96
+ }
97
+ elseif ($myinv.ScriptName) {
98
+ if ($env:TERM_PROGRAM -eq 'vscode') {
99
+ # If we are running in vscode, we know the file:line:col links are clickable so we use this format
100
+ $posmsg = "${resetcolor}$($myinv.ScriptName):$($myinv.ScriptLineNumber):$($myinv.OffsetInLine)${newline}"
101
+ }
102
+ else {
103
+ $posmsg = "${resetcolor}$($myinv.ScriptName):$($myinv.ScriptLineNumber)${newline}"
104
+ }
105
+ }
106
+ else {
107
+ $posmsg = "${newline}"
108
+ }
109
+
110
+ if ($useTargetObject) {
111
+ $scriptLineNumber = $_.TargetObject.Line
112
+ $scriptLineNumberLength = $_.TargetObject.Line.ToString().Length
113
+ }
114
+ else {
115
+ $scriptLineNumber = $myinv.ScriptLineNumber
116
+ $scriptLineNumberLength = $myinv.ScriptLineNumber.ToString().Length
117
+ }
118
+
119
+ if ($scriptLineNumberLength -gt 4) {
120
+ $headerWhitespace = ' ' * ($scriptLineNumberLength - 4)
121
+ }
122
+
123
+ $lineWhitespace = ''
124
+ if ($scriptLineNumberLength -lt 4) {
125
+ $lineWhitespace = ' ' * (4 - $scriptLineNumberLength)
126
+ }
127
+
128
+ $verticalBar = '|'
129
+ $posmsg += "${accentColor}${headerWhitespace}Line ${verticalBar}${newline}"
130
+
131
+ $highlightLine = ''
132
+ if ($useTargetObject) {
133
+ $line = $_.TargetObject.LineText.Trim()
134
+ $offsetLength = 0
135
+ $offsetInLine = 0
136
+ }
137
+ else {
138
+ $positionMessage = $myinv.PositionMessage.Split($newline)
139
+ $line = $positionMessage[1].Substring(1) # skip the '+' at the start
140
+ $highlightLine = $positionMessage[$positionMessage.Count - 1].Substring(1)
141
+ $offsetLength = $highlightLine.Trim().Length
142
+ $offsetInLine = $highlightLine.IndexOf('~')
143
+ }
144
+
145
+ if (-not $line.EndsWith($newline)) {
146
+ $line += $newline
147
+ }
148
+
149
+ # don't color the whole line
150
+ if ($offsetLength -lt $line.Length - 1) {
151
+ $line = $line.Insert($offsetInLine + $offsetLength, $resetColor).Insert($offsetInLine, $accentColor)
152
+ }
153
+
154
+ $posmsg += "${accentColor}${lineWhitespace}${ScriptLineNumber} ${verticalBar} ${resetcolor}${line}"
155
+ $offsetWhitespace = ' ' * $offsetInLine
156
+ $prefix = "${accentColor}${headerWhitespace} ${verticalBar} ${errorColor}"
157
+ if ($highlightLine -ne '') {
158
+ $posMsg += "${prefix}${highlightLine}${newline}"
159
+ }
160
+ $message = "${prefix}"
161
+ }
162
+
163
+ if (! $err.ErrorDetails -or ! $err.ErrorDetails.Message) {
164
+ if ($err.CategoryInfo.Category -eq 'ParserError' -and $err.Exception.Message.Contains("~$newline")) {
165
+ # need to parse out the relevant part of the pre-rendered positionmessage
166
+ $message += $err.Exception.Message.split("~$newline")[1].split("${newline}${newline}")[0]
167
+ }
168
+ elseif ($err.Exception) {
169
+ $message += $err.Exception.Message
170
+ }
171
+ elseif ($err.Message) {
172
+ $message += $err.Message
173
+ }
174
+ else {
175
+ $message += $err.ToString()
176
+ }
177
+ }
178
+ else {
179
+ $message += $err.ErrorDetails.Message
180
+ }
181
+
182
+ # if rendering line information, break up the message if it's wider than the console
183
+ if ($myinv -and $myinv.ScriptName -or $err.CategoryInfo.Category -eq 'ParserError') {
184
+ $prefixLength = "$([char]27)]8;;{0}`a{1}$([char]27)]8;;`a" -f $pwd, $pwd::new($prefix).ContentLength
185
+ $prefixVtLength = $prefix.Length - $prefixLength
186
+
187
+ # replace newlines in message so it lines up correct
188
+ $message = $message.Replace($newline, ' ').Replace("`n", ' ').Replace("`t", ' ')
189
+
190
+ $windowWidth = 120
191
+ if ($Host.UI.RawUI -ne $null) {
192
+ $windowWidth = $Host.UI.RawUI.WindowSize.Width
193
+ }
194
+
195
+ if ($windowWidth -gt 0 -and ($message.Length - $prefixVTLength) -gt $windowWidth) {
196
+ $sb = [Text.StringBuilder]::new()
197
+ $substring = Get-TruncatedString -string $message -length ($windowWidth + $prefixVTLength)
198
+ $null = $sb.Append($substring)
199
+ $remainingMessage = $message.Substring($substring.Length).Trim()
200
+ $null = $sb.Append($newline)
201
+ while (($remainingMessage.Length + $prefixLength) -gt $windowWidth) {
202
+ $subMessage = $prefix + $remainingMessage
203
+ $substring = Get-TruncatedString -string $subMessage -length ($windowWidth + $prefixVtLength)
204
+
205
+ if ($substring.Length - $prefix.Length -gt 0)
206
+ {
207
+ $null = $sb.Append($substring)
208
+ $null = $sb.Append($newline)
209
+ $remainingMessage = $remainingMessage.Substring($substring.Length - $prefix.Length).Trim()
210
+ }
211
+ else
212
+ {
213
+ break
214
+ }
215
+ }
216
+ $null = $sb.Append($prefix + $remainingMessage.Trim())
217
+ $message = $sb.ToString()
218
+ }
219
+
220
+ $message += $newline
221
+ }
222
+
223
+ $posmsg += "${errorColor}" + $message
224
+
225
+ $reason = 'Error'
226
+ if ($err.Exception -and $err.Exception.WasThrownFromThrowStatement) {
227
+ $reason = 'Exception'
228
+ }
229
+ # MyCommand can be the script block, so we don't want to show that so check if it's an actual command
230
+ elseif ($myinv.MyCommand -and $myinv.MyCommand.Name -and (Get-Command -Name $myinv.MyCommand -ErrorAction Ignore))
231
+ {
232
+ $reason = $myinv.MyCommand
233
+ }
234
+ # If it's a scriptblock, better to show the command in the scriptblock that had the error
235
+ elseif ($_.CategoryInfo.Activity) {
236
+ $reason = $_.CategoryInfo.Activity
237
+ }
238
+ elseif ($myinv.MyCommand) {
239
+ $reason = $myinv.MyCommand
240
+ }
241
+ elseif ($myinv.InvocationName) {
242
+ $reason = $myinv.InvocationName
243
+ }
244
+ elseif ($err.CategoryInfo.Category) {
245
+ $reason = $err.CategoryInfo.Category
246
+ }
247
+ elseif ($err.CategoryInfo.Reason) {
248
+ $reason = $err.CategoryInfo.Reason
249
+ }
250
+
251
+ $errorMsg = 'Error'
252
+
253
+ "${errorColor}${reason}: ${posmsg}${resetcolor}"
254
+ }
255
+
256
+ $myinv = $_.InvocationInfo
257
+ $err = $_
258
+ if (!$myinv -and $_.ErrorRecord -and $_.ErrorRecord.InvocationInfo) {
259
+ $err = $_.ErrorRecord
260
+ $myinv = $err.InvocationInfo
261
+ }
262
+
263
+ if ($err.FullyQualifiedErrorId -eq 'NativeCommandErrorMessage' -or $err.FullyQualifiedErrorId -eq 'NativeCommandError') {
264
+ return "${errorColor}$($err.Exception.Message)${resetcolor}"
265
+ }
266
+
267
+ $myinv = $err.InvocationInfo
268
+ if ($ErrorView -eq 'DetailedView') {
269
+ $message = Get-Error
270
+ return "${errorColor}${message}${resetcolor}"
271
+ }
272
+
273
+ if ($ErrorView -eq 'CategoryView') {
274
+ $message = $err.CategoryInfo.GetMessage()
275
+ return "${errorColor}${message}${resetcolor}"
276
+ }
277
+
278
+ $posmsg = ''
279
+ if ($ErrorView -eq 'ConciseView') {
280
+ $posmsg = Get-ConciseViewPositionMessage
281
+ }
282
+ elseif ($myinv -and ($myinv.MyCommand -or ($err.CategoryInfo.Category -ne 'ParserError'))) {
283
+ $posmsg = $myinv.PositionMessage
284
+ }
285
+
286
+ if ($posmsg -ne '') {
287
+ $posmsg = $newline + $posmsg
288
+ }
289
+
290
+ if ($err.PSMessageDetails) {
291
+ $posmsg = ' : ' + $err.PSMessageDetails + $posmsg
292
+ }
293
+
294
+ if ($ErrorView -eq 'ConciseView') {
295
+ if ($err.PSMessageDetails) {
296
+ $posmsg = "${errorColor}${posmsg}"
297
+ }
298
+ return $posmsg
299
+ }
300
+
301
+ $indent = 4
302
+
303
+ $errorCategoryMsg = $err.ErrorCategory_Message
304
+
305
+ if ($null -ne $errorCategoryMsg)
306
+ {
307
+ $indentString = '+ CategoryInfo : ' + $err.ErrorCategory_Message
308
+ }
309
+ else
310
+ {
311
+ $indentString = '+ CategoryInfo : ' + $err.CategoryInfo
312
+ }
313
+
314
+ $posmsg += $newline + $indentString
315
+
316
+ $indentString = "+ FullyQualifiedErrorId : " + $err.FullyQualifiedErrorId
317
+ $posmsg += $newline + $indentString
318
+
319
+ $originInfo = $err.OriginInfo
320
+
321
+ if (($null -ne $originInfo) -and ($null -ne $originInfo.PSComputerName))
322
+ {
323
+ $indentString = "+ PSComputerName : " + $originInfo.PSComputerName
324
+ $posmsg += $newline + $indentString
325
+ }
326
+
327
+ $finalMsg = if ($err.ErrorDetails.Message) {
328
+ $err.ErrorDetails.Message + $posmsg
329
+ } else {
330
+ $err.Exception.Message + $posmsg
331
+ }
332
+
333
+ "${errorColor}${finalMsg}${resetcolor}"
334
+
335
+ #>
0 commit comments