diff --git a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs index 3d6257f36a8..747c083ee51 100644 --- a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs +++ b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs @@ -1075,6 +1075,8 @@ private static IEnumerable ViewsOf_System_Management_Autom ") .AddScriptBlockExpressionBinding(@" Set-StrictMode -Off + $ErrorActionPreference = 'Stop' + trap { 'Error found in error view definition: ' + $_.Exception.Message } $newline = [Environment]::Newline $resetColor = '' @@ -1105,8 +1107,11 @@ function Get-ConciseViewPositionMessage { $message = '' $prefix = '' - # Don't show line information if script module - if (($myinv -and $myinv.ScriptName -or $myinv.ScriptLineNumber -gt 1 -or $err.CategoryInfo.Category -eq 'ParserError') -and !($myinv.ScriptName.EndsWith('.psm1', [System.StringComparison]::OrdinalIgnoreCase))) { + # The checks here determine if we show line detailed error information: + # - check if `ParserError` and comes from PowerShell which eventually results in a ParseException, but during this execution it's an ErrorRecord + # - check if invocation is a script or multiple lines in the console + # - 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 + 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$') { $useTargetObject = $false # Handle case where there is a TargetObject and we can show the error at the target rather than the script source diff --git a/test/powershell/engine/Formatting/ErrorView.Tests.ps1 b/test/powershell/engine/Formatting/ErrorView.Tests.ps1 index 18173354a65..2188648872a 100644 --- a/test/powershell/engine/Formatting/ErrorView.Tests.ps1 +++ b/test/powershell/engine/Formatting/ErrorView.Tests.ps1 @@ -109,7 +109,7 @@ Describe 'Tests for $ErrorView' -Tag CI { } It "Error shows if `$PSModuleAutoLoadingPreference is set to 'none'" { - $e = & "$PSHOME/pwsh" -noprofile -command '$PSModuleAutoLoadingPreference = ""none""; cmdletThatDoesntExist' 2>&1 | Out-String + $e = & "$PSHOME/pwsh" -noprofile -command '$PSModuleAutoLoadingPreference = "none"; cmdletThatDoesntExist' 2>&1 | Out-String $e | Should -BeLike "*cmdletThatDoesntExist*" } @@ -151,6 +151,21 @@ Describe 'Tests for $ErrorView' -Tag CI { $e | Should -Not -BeNullOrEmpty $e | Should -Not -BeLike "*Line*" } + + It 'Parser error shows line information' { + $testScript = '$psstyle.outputrendering = "plaintext"; 1 ++ 1' + $e = & "$PSHOME/pwsh" -noprofile -command $testScript 2>&1 | Out-String + $e | Should -Not -BeNullOrEmpty + $e = $e.Split([Environment]::NewLine) + $e[0] | Should -BeLike "ParserError:*" + $e[1] | Should -BeLike "Line *" -Because ($e | Out-String) + $e[2] | Should -BeLike "*|*1 ++ 1*" + } + + It 'Faux remote parser error shows concise message' { + start-job { [cmdletbinding()]param() $e = [System.Management.Automation.ErrorRecord]::new([System.Exception]::new('hello'), 1, 'ParserError', $null); $pscmdlet.ThrowTerminatingError($e) } | Wait-Job | Receive-Job -ErrorVariable e -ErrorAction SilentlyContinue + $e | Out-String | Should -BeLike '*ParserError*' + } } Context 'NormalView tests' {