Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ export type ExceptionRendererProps = {

renderUndefinedTrace: (exception: ErrorTrackingException, knownException?: KnownException) => React.ReactNode
renderResolvedTrace: StackTraceRenderer
renderFilteredTrace: (exception: ErrorTrackingException, knownException?: KnownException) => React.ReactNode
renderFilteredTrace: (
allFrames: ErrorTrackingStackFrame[],
exception: ErrorTrackingException,
knownException?: KnownException
) => React.ReactNode
}

export function ExceptionRenderer({
Expand All @@ -43,13 +47,13 @@ export function ExceptionRenderer({
.when(
(stack) => stack!.type === 'resolved',
(stack) => {
let frames = frameFilter ? stack!.frames.filter(frameFilter) : stack!.frames
return match(frames)
let filteredFrames = frameFilter ? stack!.frames.filter(frameFilter) : stack!.frames
return match(filteredFrames)
.when(
(frames) => Array.isArray(frames) && frames.length > 0,
(frames) => renderResolvedTrace(frames, exception, knownException)
)
.otherwise(() => renderFilteredTrace(exception, knownException))
.otherwise(() => renderFilteredTrace(stack!.frames, exception, knownException))
}
)
.otherwise(() => null)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { useValues } from 'kea'
import { useEffect } from 'react'

import { cn } from 'lib/utils/css-classes'

import { CollapsibleExceptionHeader } from '../Exception/CollapsibleExceptionHeader'
import { ExceptionRenderer } from '../Exception/ExceptionRenderer'
import { CollapsibleFrame } from '../Frame/CollapsibleFrame'
import { EmptyStackTrace } from '../StackTrace/EmptyStackTrace'
import { FilteredStackTrace } from '../StackTrace/FilteredStackTrace'
import { StackTraceRenderer } from '../StackTrace/StackTraceRenderer'
import { errorPropertiesLogic } from '../errorPropertiesLogic'
import { ErrorTrackingStackFrame } from '../types'
Expand All @@ -23,14 +25,26 @@ export function CollapsibleExceptionList({
onFrameOpenChange?: (open: boolean) => void
className?: string
}): JSX.Element {
const { exceptionList, getExceptionFingerprint, exceptionAttributes, stackFrameRecords, stackFrameRecordsLoading } =
useValues(errorPropertiesLogic)
const {
exceptionList,
getExceptionFingerprint,
exceptionAttributes,
stackFrameRecords,
stackFrameRecordsLoading,
hasInAppFrames,
} = useValues(errorPropertiesLogic)

useEffect(() => {
if (!hasInAppFrames) {
setShowAllFrames(true)
}
}, [hasInAppFrames])

return (
<div className={cn('flex flex-col gap-y-2', className)}>
<ExceptionListRenderer
exceptionList={exceptionList}
renderException={(exception, index) => {
renderException={(exception) => {
const part = getExceptionFingerprint(exception.id)
return (
<ExceptionRenderer
Expand All @@ -44,13 +58,13 @@ export function CollapsibleExceptionList({
runtime={exceptionAttributes?.runtime}
/>
)}
renderFilteredTrace={() => {
if (!showAllFrames && index == 0) {
// Always show frames on the first exception
setShowAllFrames(true)
}
return null
}}
renderFilteredTrace={(frames) => (
<FilteredStackTrace
framesCount={frames.length}
exceptionCount={exceptionList.length}
onShowAllFrames={() => setShowAllFrames(true)}
/>
)}
renderResolvedTrace={(frames: ErrorTrackingStackFrame[]) => (
<StackTraceRenderer
frames={frames}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useValues } from 'kea'
import { useEffect } from 'react'

import { cn } from 'lib/utils/css-classes'

Expand All @@ -21,25 +22,25 @@ export function RawExceptionList({
setShowAllFrames: (value: boolean) => void
className?: string
}): JSX.Element {
const { exceptionList, stackFrameRecords } = useValues(errorPropertiesLogic)
const { exceptionList, stackFrameRecords, hasInAppFrames } = useValues(errorPropertiesLogic)

useEffect(() => {
if (!hasInAppFrames) {
setShowAllFrames(true)
}
}, [hasInAppFrames])

return (
<div className={cn('flex flex-col gap-y-2', className)}>
<ExceptionListRenderer
exceptionList={exceptionList}
renderException={(exception, index) => {
renderException={(exception) => {
return (
<ExceptionRenderer
exception={exception}
frameFilter={createFrameFilter(showAllFrames)}
renderExceptionHeader={(exception) => <RawExceptionHeader exception={exception} />}
renderFilteredTrace={() => {
if (!showAllFrames && index == 0) {
// Always show frames on the first exception
setShowAllFrames(true)
}
return null
}}
renderFilteredTrace={() => null}
renderResolvedTrace={(frames: ErrorTrackingStackFrame[]) => (
<StackTraceRenderer
frames={frames}
Expand Down
17 changes: 9 additions & 8 deletions frontend/src/lib/components/Errors/Frame/FrameContextLine.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useMemo } from 'react'

import { Language } from 'lib/components/CodeSnippet'
import { CodeLine } from 'lib/components/CodeSnippet/CodeSnippet'

Expand All @@ -12,16 +14,15 @@ export function FrameContextLine({
language: Language
highlight?: boolean
}): JSX.Element {
const sortedLines = useMemo(() => [...lines].sort((a, b) => a.number - b.number), [lines])
return (
<div className={highlight ? 'bg-fill-error-highlight' : 'bg-surface-primary'}>
{lines
.sort((l) => l.number)
.map(({ number, line }) => (
<div key={number} className="flex">
<div className="w-12 text-center">{number}</div>
<CodeLine text={line} wrapLines={true} language={language} />
</div>
))}
{sortedLines.map(({ number, line }) => (
<div key={number} className="flex">
<div className="w-12 text-center">{number}</div>
<CodeLine text={line} wrapLines={true} language={language} />
</div>
))}
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { IconBox } from '@posthog/icons'

import { ButtonPrimitive } from 'lib/ui/Button/ButtonPrimitives'

export function FilteredStackTrace({
framesCount,
onShowAllFrames,
}: {
framesCount: number
exceptionCount: number
onShowAllFrames: () => void
}): JSX.Element {
return (
<div className="border-1 rounded flex justify-between items-center p-1 text-secondary">
<p className="text-xs font-medium my-0 pl-1 text-secondary">{framesCount} vendor frames</p>
<ButtonPrimitive onClick={onShowAllFrames} size="xs" className="text-secondary">
<IconBox />
Show all frames
</ButtonPrimitive>
</div>
)
}
Loading