Browse Source

chore(ts): convert Frame (#20697)

Stephen Cefali 4 years ago
parent
commit
a38fb6ba83

+ 1 - 1
src/sentry/static/sentry/app/components/events/interfaces/frame/frameDefaultTitle.tsx

@@ -160,7 +160,7 @@ const FrameDefaultTitle = ({frame, platform}: Props) => {
     );
   }
 
-  return title;
+  return <React.Fragment>{title}</React.Fragment>;
 };
 
 const StyledExternalLink = styled(ExternalLink)`

+ 44 - 17
src/sentry/static/sentry/app/components/events/interfaces/frame/frame.jsx → src/sentry/static/sentry/app/components/events/interfaces/frame/frameLine.tsx

@@ -18,14 +18,37 @@ import {SymbolicatorStatus} from 'app/components/events/interfaces/types';
 import {combineStatus} from 'app/components/events/interfaces/debugMeta/utils';
 import {IconRefresh, IconAdd, IconSubtract, IconQuestion, IconWarning} from 'app/icons';
 import overflowEllipsis from 'app/styles/overflowEllipsis';
+import {Frame, SentryAppComponent, PlatformType} from 'app/types';
+import DebugImage from 'app/components/events/interfaces/debugMeta/debugImage';
 
 import FrameDefaultTitle from './frameDefaultTitle';
 import FrameContext from './frameContext';
 import FrameFunctionName from './frameFunctionName';
 import {getPlatform} from './utils';
 
-export class Frame extends React.Component {
-  static propTypes = {
+type Props = {
+  data: Frame;
+  nextFrame: Frame;
+  prevFrame: Frame;
+  platform: PlatformType;
+  isExpanded: boolean;
+  emptySourceNotation: boolean;
+  isOnlyFrame: boolean;
+  timesRepeated: number;
+  registers: Record<string, string>;
+  components: Array<SentryAppComponent>;
+  showingAbsoluteAddress: boolean;
+  onAddressToggle: () => void;
+  image: React.ComponentProps<typeof DebugImage>['image'];
+  maxLengthOfRelativeAddress: number;
+};
+
+type State = {
+  isExpanded: boolean;
+};
+
+export class FrameLine extends React.Component<Props, State> {
+  static propTypes: any = {
     data: PropTypes.object.isRequired,
     nextFrame: PropTypes.object,
     prevFrame: PropTypes.object,
@@ -63,7 +86,7 @@ export class Frame extends React.Component {
   };
 
   hasContextSource() {
-    return defined(this.props.data.context) && this.props.data.context.length;
+    return defined(this.props.data.context) && !!this.props.data.context.length;
   }
 
   hasContextVars() {
@@ -105,7 +128,9 @@ export class Frame extends React.Component {
   shouldShowLinkToImage() {
     const {symbolicatorStatus} = this.props.data;
 
-    return symbolicatorStatus && symbolicatorStatus !== SymbolicatorStatus.UNKNOWN_IMAGE;
+    return (
+      !!symbolicatorStatus && symbolicatorStatus !== SymbolicatorStatus.UNKNOWN_IMAGE
+    );
   }
 
   packageStatus() {
@@ -169,7 +194,7 @@ export class Frame extends React.Component {
     const {symbolicatorStatus} = this.props.data;
     const func = this.props.data.function || '<unknown>';
     // Custom color used to match adjacent text.
-    const warningIcon = <IconQuestion size="xs" color="#2c45a8" />;
+    const warningIcon = <IconQuestion size="xs" color={'#2c45a8' as any} />;
     const errorIcon = <IconWarning size="xs" color="red400" />;
 
     if (func.match(/^@objc\s/)) {
@@ -238,7 +263,7 @@ export class Frame extends React.Component {
 
   renderDefaultLine() {
     return (
-      <StrictClick onClick={this.isExpandable() ? this.toggleContext : null}>
+      <StrictClick onClick={this.isExpandable() ? this.toggleContext : undefined}>
         <DefaultLine className="title">
           <VertCenterWrapper>
             <div>
@@ -267,7 +292,7 @@ export class Frame extends React.Component {
     const leadHint = this.renderLeadHint();
 
     return (
-      <StrictClick onClick={this.isExpandable() ? this.toggleContext : null}>
+      <StrictClick onClick={this.isExpandable() ? this.toggleContext : undefined}>
         <DefaultLine className="title as-table">
           <NativeLineContent>
             <PackageInfo>
@@ -281,15 +306,17 @@ export class Frame extends React.Component {
                 <PackageStatus status={this.packageStatus()} />
               </PackageLink>
             </PackageInfo>
-            <TogglableAddress
-              address={data.instructionAddr}
-              startingAddress={image ? image.image_addr : null}
-              isAbsolute={showingAbsoluteAddress}
-              isFoundByStackScanning={this.isFoundByStackScanning()}
-              isInlineFrame={this.isInlineFrame()}
-              onToggle={onAddressToggle}
-              maxLengthOfRelativeAddress={maxLengthOfRelativeAddress}
-            />
+            {data.instructionAddr && (
+              <TogglableAddress
+                address={data.instructionAddr}
+                startingAddress={image ? image.image_addr : null}
+                isAbsolute={showingAbsoluteAddress}
+                isFoundByStackScanning={this.isFoundByStackScanning()}
+                isInlineFrame={this.isInlineFrame()}
+                onToggle={onAddressToggle}
+                maxLengthOfRelativeAddress={maxLengthOfRelativeAddress}
+              />
+            )}
             <Symbol className="symbol">
               <FrameFunctionName frame={data} />{' '}
               {hint !== null ? (
@@ -444,4 +471,4 @@ const LeadHint = styled('div')`
   width: 67px;
 `;
 
-export default withSentryAppComponents(Frame, {componentType: 'stacktrace-link'});
+export default withSentryAppComponents(FrameLine, {componentType: 'stacktrace-link'});

+ 2 - 2
src/sentry/static/sentry/app/components/events/interfaces/packageLink.tsx

@@ -10,10 +10,10 @@ import {PackageStatusIcon} from 'app/components/events/interfaces/packageStatus'
 import overflowEllipsis from 'app/styles/overflowEllipsis';
 
 type Props = {
-  packagePath: string;
   onClick: (event: React.MouseEvent<HTMLAnchorElement>) => void;
-  isClickable: boolean;
   withLeadHint: boolean;
+  packagePath?: string;
+  isClickable?: boolean;
 };
 
 class PackageLink extends React.Component<Props> {

+ 2 - 2
src/sentry/static/sentry/app/components/events/interfaces/stacktraceContent.jsx

@@ -1,7 +1,7 @@
 import PropTypes from 'prop-types';
 import React from 'react';
 
-import Frame from 'app/components/events/interfaces/frame/frame';
+import FrameLine from 'app/components/events/interfaces/frame/frameLine';
 import {t} from 'app/locale';
 import SentryTypes from 'app/sentryTypes';
 import {parseAddress, getImageRange} from 'app/components/events/interfaces/utils';
@@ -127,7 +127,7 @@ export default class StacktraceContent extends React.Component {
         const image = this.findImageForAddress(frame.instructionAddr);
 
         frames.push(
-          <Frame
+          <FrameLine
             key={frameIdx}
             data={frame}
             isExpanded={expandFirstFrame && lastFrameIdx === frameIdx}

+ 2 - 2
src/sentry/static/sentry/app/components/events/interfaces/template.jsx

@@ -3,7 +3,7 @@ import React from 'react';
 
 import EventDataSection from 'app/components/events/eventDataSection';
 import SentryTypes from 'app/sentryTypes';
-import Frame from 'app/components/events/interfaces/frame/frame';
+import FrameLine from 'app/components/events/interfaces/frame/frameLine';
 import {t} from 'app/locale';
 
 class TemplateInterface extends React.Component {
@@ -22,7 +22,7 @@ class TemplateInterface extends React.Component {
       >
         <div className="traceback no-exception">
           <ul>
-            <Frame data={this.props.data} isExpanded />
+            <FrameLine data={this.props.data} isExpanded />
           </ul>
         </div>
       </EventDataSection>

+ 1 - 1
src/sentry/static/sentry/app/components/strictClick.tsx

@@ -5,7 +5,7 @@ type ClickProps<T> = {
 };
 
 type Props<T extends HTMLElement> = ClickProps<T> & {
-  children: React.ReactHTMLElement<T>;
+  children: React.ReactElement<T>;
 };
 
 type State = {

+ 4 - 1
src/sentry/static/sentry/app/types/index.tsx

@@ -11,6 +11,7 @@ import {
 import {WIDGET_DISPLAY} from 'app/views/dashboards/constants';
 import {Props as AlertProps} from 'app/components/alert';
 import {Query as DiscoverQuery} from 'app/views/discover/types';
+import {SymbolicatorStatus} from 'app/components/events/interfaces/types';
 
 declare global {
   interface Window {
@@ -1410,7 +1411,7 @@ export type Widget = {
 
 export type EventGroupInfo = Record<EventGroupVariantKey, EventGroupVariant>;
 
-export type PlatformType = 'java' | 'csharp' | 'other';
+export type PlatformType = 'java' | 'csharp' | 'objc' | 'cocoa' | 'native' | 'other';
 
 export type Frame = {
   filename: string;
@@ -1431,6 +1432,8 @@ export type Frame = {
   origAbsPath?: string;
   mapUrl?: string;
   instructionAddr?: string;
+  trust?: string;
+  symbolicatorStatus?: SymbolicatorStatus;
 };
 
 /**

+ 0 - 8
tests/js/spec/components/events/interfaces/__snapshots__/frame.spec.jsx.snap

@@ -1,8 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Frame renderOriginalSourceInfo() should render the source map information as a HTML string 1`] = `
-<FrameDefaultTitleOriginalSourceInfo
-  map="vendor.js.map"
-  mapUrl="https://beta.getsentry.com/_static/sentry/dist/vendor.js.map"
-/>
-`;

+ 91 - 0
tests/js/spec/components/events/interfaces/__snapshots__/frameLine.spec.jsx.snap

@@ -0,0 +1,91 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Frame renderContext() should render context lines 1`] = `
+Array [
+  <ContextLine
+    className="css-x7wq2i-FrameContext"
+    isActive={false}
+    line={
+      Array [
+        211,
+        "    # Mark the crashed thread and add its stacktrace to the exception",
+      ]
+    }
+  >
+    <li
+      className="css-x7wq2i-FrameContext expandable"
+      key="211"
+    >
+      <span
+        className="ws"
+      >
+            
+      </span>
+      <span
+        className="contextline"
+      >
+        # Mark the crashed thread and add its stacktrace to the exception
+      </span>
+    </li>
+  </ContextLine>,
+  <ContextLine
+    className="css-x7wq2i-FrameContext"
+    isActive={false}
+    line={
+      Array [
+        212,
+        "    crashed_thread = data['threads'][state.requesting_thread]",
+      ]
+    }
+  >
+    <li
+      className="css-x7wq2i-FrameContext expandable"
+      key="212"
+    >
+      <span
+        className="ws"
+      >
+            
+      </span>
+      <span
+        className="contextline"
+      >
+        crashed_thread = data['threads'][state.requesting_thread]
+      </span>
+    </li>
+  </ContextLine>,
+  <ContextLine
+    className="css-x7wq2i-FrameContext"
+    isActive={false}
+    line={
+      Array [
+        213,
+        "    crashed_thread['crashed'] = True",
+      ]
+    }
+  >
+    <li
+      className="css-x7wq2i-FrameContext expandable"
+      key="213"
+    >
+      <span
+        className="ws"
+      >
+            
+      </span>
+      <span
+        className="contextline"
+      >
+        crashed_thread['crashed'] = True
+      </span>
+    </li>
+  </ContextLine>,
+]
+`;
+
+exports[`Frame renderOriginalSourceInfo() should render the source map information as a HTML string 1`] = `
+<FrameDefaultTitleOriginalSourceInfo
+  map="vendor.js.map"
+  mapUrl="https://beta.getsentry.com/_static/sentry/dist/vendor.js.map"
+/>
+`;

+ 2 - 2
tests/js/spec/components/events/interfaces/exceptionStacktraceContent.spec.jsx

@@ -114,7 +114,7 @@ describe('ExceptionStacktraceContent', () => {
 
   it('should render system frames if "stackView: app" and there are no inApp frames and is a chained exceptions', () => {
     const wrapper = mount(<ExceptionStacktraceContent {...props} chainedException />);
-    expect(wrapper.find('Frame').length).toBe(2);
+    expect(wrapper.find('FrameLine').length).toBe(2);
   });
 
   it('should not render system frames if "stackView: app" and there are inApp frames and is a chained exceptions', () => {
@@ -123,7 +123,7 @@ describe('ExceptionStacktraceContent', () => {
     const wrapper = mount(
       <ExceptionStacktraceContent {...modifiedProps} chainedException />
     );
-    expect(wrapper.find('Frame').length).toBe(1);
+    expect(wrapper.find('FrameLine').length).toBe(1);
     expect(wrapper.find('.filename').text()).toBe(props.stacktrace.frames[0].filename);
   });
 });

Some files were not shown because too many files changed in this diff