123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- import {useState} from 'react';
- import EventDataSection from 'sentry/components/events/eventDataSection';
- import CrashActions from 'sentry/components/events/interfaces/crashHeader/crashActions';
- import CrashTitle from 'sentry/components/events/interfaces/crashHeader/crashTitle';
- import {t} from 'sentry/locale';
- import {Event, Project, STACK_TYPE, STACK_VIEW, Thread} from 'sentry/types';
- import {defined} from 'sentry/utils';
- import {isStacktraceNewestFirst} from '../utils';
- import findBestThread from './threadSelector/findBestThread';
- import getThreadException from './threadSelector/getThreadException';
- import getThreadStacktrace from './threadSelector/getThreadStacktrace';
- import Content from './content';
- import ThreadSelector from './threadSelector';
- type Props = Pick<
- React.ComponentProps<typeof Content>,
- 'groupingCurrentLevel' | 'hasHierarchicalGrouping'
- > & {
- data: {
- values?: Array<Thread>;
- };
- event: Event;
- projectId: Project['id'];
- type: string;
- hideGuide?: boolean;
- };
- type State = {
- newestFirst: boolean;
- stackType: STACK_TYPE;
- activeThread?: Thread;
- stackView?: STACK_VIEW;
- };
- function getIntendedStackView(thread: Thread, event: Event) {
- const exception = getThreadException(event, thread);
- if (exception) {
- return !!exception.values.find(value => !!value.stacktrace?.hasSystemFrames)
- ? STACK_VIEW.APP
- : STACK_VIEW.FULL;
- }
- const stacktrace = getThreadStacktrace(false, thread);
- return stacktrace?.hasSystemFrames ? STACK_VIEW.APP : STACK_VIEW.FULL;
- }
- function Threads({
- data,
- event,
- projectId,
- type,
- hasHierarchicalGrouping,
- groupingCurrentLevel,
- hideGuide = false,
- }: Props) {
- const [state, setState] = useState<State>(() => {
- const thread = defined(data.values) ? findBestThread(data.values) : undefined;
- return {
- activeThread: thread,
- stackView: thread ? getIntendedStackView(thread, event) : undefined,
- stackType: STACK_TYPE.ORIGINAL,
- newestFirst: isStacktraceNewestFirst(),
- };
- });
- if (!data.values) {
- return null;
- }
- function handleSelectNewThread(thread: Thread) {
- setState({
- ...state,
- activeThread: thread,
- stackView:
- state.stackView !== STACK_VIEW.RAW
- ? getIntendedStackView(thread, event)
- : state.stackView,
- stackType: STACK_TYPE.ORIGINAL,
- });
- }
- function handleChangeNewestFirst({newestFirst}: Pick<State, 'newestFirst'>) {
- setState({...state, newestFirst});
- }
- function handleChangeStackView({
- stackView,
- stackType,
- }: Partial<Pick<State, 'stackType' | 'stackView'>>) {
- setState({
- ...state,
- stackView: stackView ?? state.stackView,
- stackType: stackType ?? state.stackType,
- });
- }
- const threads = data.values;
- const {stackView, stackType, newestFirst, activeThread} = state;
- const exception = getThreadException(event, activeThread);
- const stacktrace = !exception
- ? getThreadStacktrace(stackType !== STACK_TYPE.ORIGINAL, activeThread)
- : undefined;
- const stackTraceNotFound = !(exception || stacktrace);
- const hasMoreThanOneThread = threads.length > 1;
- return (
- <EventDataSection
- type={type}
- title={
- hasMoreThanOneThread ? (
- <CrashTitle
- title=""
- newestFirst={newestFirst}
- hideGuide={hideGuide}
- onChange={handleChangeNewestFirst}
- beforeTitle={
- activeThread && (
- <ThreadSelector
- threads={threads}
- activeThread={activeThread}
- event={event}
- onChange={handleSelectNewThread}
- exception={exception}
- />
- )
- }
- />
- ) : (
- <CrashTitle
- title={t('Stack Trace')}
- newestFirst={newestFirst}
- hideGuide={hideGuide}
- onChange={!stackTraceNotFound ? handleChangeNewestFirst : undefined}
- />
- )
- }
- actions={
- !stackTraceNotFound && (
- <CrashActions
- stackView={stackView}
- platform={event.platform}
- stacktrace={stacktrace}
- stackType={stackType}
- thread={hasMoreThanOneThread ? activeThread : undefined}
- exception={exception}
- onChange={handleChangeStackView}
- hasHierarchicalGrouping={hasHierarchicalGrouping}
- />
- )
- }
- showPermalink={!hasMoreThanOneThread}
- wrapTitle={false}
- >
- <Content
- data={activeThread}
- exception={exception}
- stackView={stackView}
- stackType={stackType}
- stacktrace={stacktrace}
- event={event}
- newestFirst={newestFirst}
- projectId={projectId}
- groupingCurrentLevel={groupingCurrentLevel}
- stackTraceNotFound={stackTraceNotFound}
- hasHierarchicalGrouping={hasHierarchicalGrouping}
- />
- </EventDataSection>
- );
- }
- export default Threads;
|