From 41b91a6e86b7c7e5a7ff232a93f1499567d3d0e7 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Thu, 4 Jul 2024 12:30:10 +0200 Subject: [PATCH 1/6] prepare tests before the fix --- .../Sentry/private/StackTraceProcessor.ps1 | 2 +- modules/Sentry/public/Out-Sentry.ps1 | 2 +- scripts/bump-version.sh | 2 +- tests/stacktrace-processor.tests.ps1 | 28 +++++++++++++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 tests/stacktrace-processor.tests.ps1 diff --git a/modules/Sentry/private/StackTraceProcessor.ps1 b/modules/Sentry/private/StackTraceProcessor.ps1 index 19cab44..399b0bc 100644 --- a/modules/Sentry/private/StackTraceProcessor.ps1 +++ b/modules/Sentry/private/StackTraceProcessor.ps1 @@ -210,7 +210,7 @@ class StackTraceProcessor : SentryEventProcessor { $sentryFrame = [Sentry.SentryStackFrame]::new() # at funcB, C:\dev\sentry-powershell\tests\capture.tests.ps1: line 363 - $regex = 'at (?[^,]+), (?.+): line (?\d+)' + $regex = 'at (?[^,]*), (?.*): line (?\d*)' if ($frame -match $regex) { $sentryFrame.AbsolutePath = $Matches.AbsolutePath diff --git a/modules/Sentry/public/Out-Sentry.ps1 b/modules/Sentry/public/Out-Sentry.ps1 index c670fb8..f549373 100644 --- a/modules/Sentry/public/Out-Sentry.ps1 +++ b/modules/Sentry/public/Out-Sentry.ps1 @@ -64,7 +64,7 @@ function Out-Sentry { # Note: we use ScriptStackTrace even though we need to parse it, becaause it contains actual stack trace # to the throw, not just the trace to the call to this function. - $processor.StackTraceString = $ErrorRecord.ScriptStackTrace -split "[`r`n]+" | Where-Object { $_ -ne 'at , : line 1' } + $processor.StackTraceString = $ErrorRecord.ScriptStackTrace -split "[`r`n]+" $processor.InvocationInfo = $ErrorRecord.InvocationInfo } diff --git a/scripts/bump-version.sh b/scripts/bump-version.sh index a4848ca..9bb2bbe 100644 --- a/scripts/bump-version.sh +++ b/scripts/bump-version.sh @@ -2,5 +2,5 @@ set -euxo pipefail # Requires powershell: `brew install powershell` -# craft executes this file by convension, passing the new version as the second argument: +# craft executes this file by convention, passing the new version as the second argument: pwsh ./scripts/bump-version.ps1 "$2" diff --git a/tests/stacktrace-processor.tests.ps1 b/tests/stacktrace-processor.tests.ps1 new file mode 100644 index 0000000..2926e37 --- /dev/null +++ b/tests/stacktrace-processor.tests.ps1 @@ -0,0 +1,28 @@ +BeforeAll { + . "$PSScriptRoot/../modules/Sentry/private/StackTraceProcessor.ps1" +} + +Describe 'StackTraceProcessor' { + It 'Parses stack trace properly' { + $event_ = [Sentry.SentryEvent]::new() + $event_.Message = 'Test' + $event_.Level = [Sentry.SentryLevel]::Info + + $sut = [StackTraceProcessor]::new() + $sut.StackTraceString = 'at funcB, C:\dev\sentry-powershell\tests\throwing.ps1: line 17 +at , : line 1 +at , : line 3' -split "[`r`n]+" + $sut.process($event_) + + $frames = $event_.SentryThreads[0].Stacktrace.Frames + $frames[0].Function | Should -Be '' + $frames[0].AbsolutePath | Should -Be '' + $frames[0].LineNumber | Should -Be 3 + $frames[1].Function | Should -Be '' + $frames[1].AbsolutePath | Should -Be '' + $frames[1].LineNumber | Should -Be 1 + $frames[2].Function | Should -Be 'funcB' + $frames[2].AbsolutePath | Should -Be 'C:\dev\sentry-powershell\tests\throwing.ps1' + $frames[2].LineNumber | Should -Be 17 + } +} From 145f1e9e766843e190de010a06822f5c968b3d50 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Thu, 4 Jul 2024 12:54:47 +0200 Subject: [PATCH 2/6] fixup --- modules/Sentry/public/Out-Sentry.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/Sentry/public/Out-Sentry.ps1 b/modules/Sentry/public/Out-Sentry.ps1 index f549373..c605a1c 100644 --- a/modules/Sentry/public/Out-Sentry.ps1 +++ b/modules/Sentry/public/Out-Sentry.ps1 @@ -64,7 +64,7 @@ function Out-Sentry { # Note: we use ScriptStackTrace even though we need to parse it, becaause it contains actual stack trace # to the throw, not just the trace to the call to this function. - $processor.StackTraceString = $ErrorRecord.ScriptStackTrace -split "[`r`n]+" + $processor.StackTraceString = @($ErrorRecord.ScriptStackTrace -split "[`r`n]+") $processor.InvocationInfo = $ErrorRecord.InvocationInfo } From 86db18eb917949778384ef3fb8f9f6c9f11b45a2 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Thu, 4 Jul 2024 13:07:31 +0200 Subject: [PATCH 3/6] fixup CI --- modules/Sentry/private/StackTraceProcessor.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/Sentry/private/StackTraceProcessor.ps1 b/modules/Sentry/private/StackTraceProcessor.ps1 index 399b0bc..784f94b 100644 --- a/modules/Sentry/private/StackTraceProcessor.ps1 +++ b/modules/Sentry/private/StackTraceProcessor.ps1 @@ -120,7 +120,7 @@ class StackTraceProcessor : SentryEventProcessor { $sentryFrames.Capacity = $this.StackTraceFrames.Count + 1 } - else + elseif ($null -ne $this.StackTraceString) { $sentryFrames.Capacity = $this.StackTraceString.Count + 1 } @@ -139,7 +139,7 @@ class StackTraceProcessor : SentryEventProcessor $sentryFrames.Add($this.CreateFrame($frame)) } } - else + elseif ($null -ne $this.StackTraceString) { # Note: if InvocationInfo is present, use it to update: # - the first frame (in case of `$_ | Out-Sentry` in a catch clause). From eb2d7d226f9bfa4fc372888a4f7dd65558d9d47e Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Thu, 4 Jul 2024 13:09:59 +0200 Subject: [PATCH 4/6] fix windows powershell --- modules/Sentry/private/StackTraceProcessor.ps1 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/Sentry/private/StackTraceProcessor.ps1 b/modules/Sentry/private/StackTraceProcessor.ps1 index 784f94b..6e3a237 100644 --- a/modules/Sentry/private/StackTraceProcessor.ps1 +++ b/modules/Sentry/private/StackTraceProcessor.ps1 @@ -177,7 +177,7 @@ class StackTraceProcessor : SentryEventProcessor { # Update module info $this.SetModule($sentryFrame) - $sentryFrame.InApp = $null -eq $sentryFrame.Module + $sentryFrame.InApp = [string]::IsNullOrEmpty($sentryFrame.Module) $this.SetContextLines($sentryFrame) } @@ -226,12 +226,12 @@ class StackTraceProcessor : SentryEventProcessor hidden SetScriptInfo([Sentry.SentryStackFrame] $sentryFrame, [System.Management.Automation.CallStackFrame] $frame) { - if ($null -ne $frame.ScriptName) + if (![string]::IsNullOrEmpty($frame.ScriptName)) { $sentryFrame.AbsolutePath = $frame.ScriptName $sentryFrame.LineNumber = $frame.ScriptLineNumber } - elseif ($null -ne $frame.Position -and $null -ne $frame.Position.File) + elseif (![string]::IsNullOrEmpty($frame.Position) -and ![string]::IsNullOrEmpty($frame.Position.File)) { $sentryFrame.AbsolutePath = $frame.Position.File $sentryFrame.LineNumber = $frame.Position.StartLineNumber @@ -241,7 +241,7 @@ class StackTraceProcessor : SentryEventProcessor hidden SetModule([Sentry.SentryStackFrame] $sentryFrame) { - if ($null -ne $sentryFrame.AbsolutePath) + if (![string]::IsNullOrEmpty($sentryFrame.AbsolutePath)) { if ($prefix = $this.modulePaths | Where-Object { $sentryFrame.AbsolutePath.StartsWith($_) }) { @@ -265,7 +265,7 @@ class StackTraceProcessor : SentryEventProcessor hidden SetFunction([Sentry.SentryStackFrame] $sentryFrame, [System.Management.Automation.CallStackFrame] $frame) { - if ($null -eq $sentryFrame.AbsolutePath -and $frame.FunctionName -eq '' -and $null -ne $frame.Position) + if ([string]::IsNullOrEmpty($sentryFrame.AbsolutePath) -and $frame.FunctionName -eq '' -and ![string]::IsNullOrEmpty($frame.Position)) { $sentryFrame.Function = $frame.Position.Text } @@ -277,7 +277,7 @@ class StackTraceProcessor : SentryEventProcessor hidden SetContextLines([Sentry.SentryStackFrame] $sentryFrame) { - if ($null -ne $sentryFrame.AbsolutePath -and $sentryFrame.LineNumber -ge 1 -and (Test-Path $sentryFrame.AbsolutePath -PathType Leaf)) + if (![string]::IsNullOrEmpty($sentryFrame.AbsolutePath) -and $sentryFrame.LineNumber -ge 1 -and (Test-Path $sentryFrame.AbsolutePath -PathType Leaf)) { try { From bc0142150acf4afd95d31508ce9f0858b6f75cd9 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Thu, 4 Jul 2024 13:13:13 +0200 Subject: [PATCH 5/6] chore: update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 647de58..6162ba7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Fixes + +- StackTrace parsing on Windows Powershell 5.1 ([#50](https://github.com/getsentry/sentry-powershell/pull/50)) + ## 0.1.0 ### Features From 5d4ccbb69337625ffbdbcf838471c6948688eade Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Thu, 4 Jul 2024 13:19:22 +0200 Subject: [PATCH 6/6] more path validation --- modules/Sentry/private/StackTraceProcessor.ps1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/Sentry/private/StackTraceProcessor.ps1 b/modules/Sentry/private/StackTraceProcessor.ps1 index 6e3a237..6ad1bca 100644 --- a/modules/Sentry/private/StackTraceProcessor.ps1 +++ b/modules/Sentry/private/StackTraceProcessor.ps1 @@ -277,7 +277,12 @@ class StackTraceProcessor : SentryEventProcessor hidden SetContextLines([Sentry.SentryStackFrame] $sentryFrame) { - if (![string]::IsNullOrEmpty($sentryFrame.AbsolutePath) -and $sentryFrame.LineNumber -ge 1 -and (Test-Path $sentryFrame.AbsolutePath -PathType Leaf)) + if ([string]::IsNullOrEmpty($sentryFrame.AbsolutePath) -or $sentryFrame.LineNumber -lt 1) + { + return + } + + if ((Test-Path $sentryFrame.AbsolutePath -IsValid) -and (Test-Path $sentryFrame.AbsolutePath -PathType Leaf)) { try {