diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b7e1ad..1032a4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Fixes - StackTrace parsing on Windows Powershell 5.1 ([#50](https://github.com/getsentry/sentry-powershell/pull/50)) +- Fix out of bounds context for short scripts ([#58](https://github.com/getsentry/sentry-powershell/pull/58)) ### Dependencies diff --git a/modules/Sentry/private/StackTraceProcessor.ps1 b/modules/Sentry/private/StackTraceProcessor.ps1 index 6ad1bca..97a59f0 100644 --- a/modules/Sentry/private/StackTraceProcessor.ps1 +++ b/modules/Sentry/private/StackTraceProcessor.ps1 @@ -291,15 +291,17 @@ class StackTraceProcessor : SentryEventProcessor { $sentryFrame.ContextLine = $lines[$sentryFrame.LineNumber - 1] } + $preContextCount = [math]::Min(5, $sentryFrame.LineNumber - 1) + $postContextCount = [math]::Min(5, $lines.Count - $sentryFrame.LineNumber) if ($sentryFrame.LineNumber -gt 6) { $lines = $lines | Select-Object -Skip ($sentryFrame.LineNumber - 6) } # Note: these are read-only in sentry-dotnet so we just update the underlying lists instead of replacing. $sentryFrame.PreContext.Clear() - $lines | Select-Object -First 5 | ForEach-Object { $sentryFrame.PreContext.Add($_) } + $lines | Select-Object -First $preContextCount | ForEach-Object { $sentryFrame.PreContext.Add($_) } $sentryFrame.PostContext.Clear() - $lines | Select-Object -Last 5 | ForEach-Object { $sentryFrame.PostContext.Add($_) } + $lines | Select-Object -Last $postContextCount | ForEach-Object { $sentryFrame.PostContext.Add($_) } } catch { diff --git a/tests/stacktrace.tests.ps1 b/tests/stacktrace.tests.ps1 index 678e964..f82dbd6 100644 --- a/tests/stacktrace.tests.ps1 +++ b/tests/stacktrace.tests.ps1 @@ -1,6 +1,7 @@ BeforeAll { . "$PSScriptRoot/utils.ps1" . "$PSScriptRoot/throwing.ps1" + . "$PSScriptRoot/throwingshort.ps1" $events = [System.Collections.Generic.List[Sentry.SentryEvent]]::new(); $transport = [RecordingTransport]::new() StartSentryForEventTests ([ref] $events) ([ref] $transport) @@ -77,6 +78,31 @@ BeforeAll { # A module-based frame should be in-app=false $frames | Where-Object -Property Module | Select-Object -First 1 -ExpandProperty 'InApp' | Should -Be $false } + + $checkShortErrorRecord = { + $events.Count | Should -Be 1 + [Sentry.SentryEvent]$event = $events.ToArray()[0] + $event.SentryExceptions.Count | Should -Be 2 + + $event.SentryExceptions[1].Type | Should -Be 'Short context test' + $event.SentryExceptions[1].Value | Should -Be 'Short context test' + $event.SentryExceptions[1].Module | Should -BeNullOrEmpty + [Sentry.SentryStackFrame[]] $frames = $event.SentryExceptions[1].Stacktrace.Frames + $frames.Count | Should -BeGreaterThan 1 + + $frame = GetListItem $frames -1 + + $frame.Function | Should -Be "funcC" + $frame.AbsolutePath | Should -Be (Join-Path $PSScriptRoot 'throwingshort.ps1') + $frame.LineNumber | Should -BeGreaterThan 0 + $frame.InApp | Should -Be $true + + $frame.PreContext | Should -Be @('function funcC {') + $frame.PreContext.Count | Should -Be 1 + $frame.ContextLine | Should -Be ' throw "Short context test"' + $frame.PostContext | Should -Be @('}') + $frame.PostContext.Count | Should -Be 1 + } } AfterAll { @@ -119,6 +145,19 @@ Describe 'Out-Sentry' { @($null) | ForEach-Object $checkErrorRecord } + It 'captures short context' { + try + { + funcC + } + catch + { + $_ | Out-Sentry + } + + @($null) | ForEach-Object $checkShortErrorRecord + } + It 'captures exception' { try { diff --git a/tests/throwingshort.ps1 b/tests/throwingshort.ps1 new file mode 100644 index 0000000..c8848a7 --- /dev/null +++ b/tests/throwingshort.ps1 @@ -0,0 +1,3 @@ +function funcC { + throw "Short context test" +} \ No newline at end of file