Improve CrashReporter UI for the latest crash
Summary: I have updated the UI of the crash reporter. It doesn't show the multiple crashes now. I will work on that in other diff. This diff just updates the current UI that shows the latest crash, as per the [design](https://our.intern.facebook.com/intern/px/p/pJ11/) Reviewed By: danielbuechele Differential Revision: D14399400 fbshipit-source-id: f6f28c2c6d386f4cd99a257922993ef355b1059b
This commit is contained in:
committed by
Facebook Github Bot
parent
8b91ec68a7
commit
574ae7a3e8
@@ -21,6 +21,11 @@ import {
|
|||||||
getPersistedState,
|
getPersistedState,
|
||||||
BaseDevice,
|
BaseDevice,
|
||||||
shouldParseAndroidLog,
|
shouldParseAndroidLog,
|
||||||
|
StackTrace,
|
||||||
|
Text,
|
||||||
|
colors,
|
||||||
|
Toolbar,
|
||||||
|
Spacer,
|
||||||
} from 'flipper';
|
} from 'flipper';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
@@ -28,6 +33,17 @@ import util from 'util';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import type {Notification} from '../../plugin';
|
import type {Notification} from '../../plugin';
|
||||||
import type {Store, DeviceLogEntry, OS} from 'flipper';
|
import type {Store, DeviceLogEntry, OS} from 'flipper';
|
||||||
|
import {Component} from 'react';
|
||||||
|
|
||||||
|
type HeaderRowProps = {
|
||||||
|
title: string,
|
||||||
|
value: string,
|
||||||
|
};
|
||||||
|
type openLogsCallbackType = () => void;
|
||||||
|
|
||||||
|
type CrashReporterBarProps = {|
|
||||||
|
openLogsCallback?: openLogsCallbackType,
|
||||||
|
|};
|
||||||
|
|
||||||
export type Crash = {|
|
export type Crash = {|
|
||||||
notificationID: string,
|
notificationID: string,
|
||||||
@@ -46,37 +62,58 @@ export type PersistedState = {
|
|||||||
crashes: Array<Crash>,
|
crashes: Array<Crash>,
|
||||||
};
|
};
|
||||||
|
|
||||||
const Title = styled(View)({
|
const Padder = styled('div')(
|
||||||
|
({paddingLeft, paddingRight, paddingBottom, paddingTop}) => ({
|
||||||
|
paddingLeft: paddingLeft || 0,
|
||||||
|
paddingRight: paddingRight || 0,
|
||||||
|
paddingBottom: paddingBottom || 0,
|
||||||
|
paddingTop: paddingTop || 0,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const Title = styled(Text)({
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
fontSize: '100%',
|
color: colors.greyTint3,
|
||||||
color: 'red',
|
height: 'auto',
|
||||||
|
width: 200,
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
});
|
});
|
||||||
|
|
||||||
const Value = styled(View)({
|
const Line = styled(View)({
|
||||||
paddingLeft: '8px',
|
backgroundColor: colors.greyTint2,
|
||||||
fontSize: '100%',
|
height: 1,
|
||||||
fontFamily: 'Monospace',
|
width: 'auto',
|
||||||
maxHeight: '200px',
|
marginTop: 2,
|
||||||
|
flexShrink: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const Container = styled(FlexColumn)({
|
||||||
|
overflow: 'hidden',
|
||||||
|
flexShrink: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const Value = styled(Title)({
|
||||||
|
maxHeight: 200,
|
||||||
|
height: 'auto',
|
||||||
|
flexGrow: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
const FlexGrowColumn = styled(FlexColumn)({
|
||||||
|
flexGrow: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
const ScrollableColumn = styled(FlexGrowColumn)({
|
||||||
overflow: 'scroll',
|
overflow: 'scroll',
|
||||||
|
height: 'auto',
|
||||||
});
|
});
|
||||||
|
|
||||||
const RootColumn = styled(FlexColumn)({
|
const StyledFlexGrowColumn = styled(FlexColumn)({
|
||||||
paddingLeft: '16px',
|
flexGrow: 1,
|
||||||
paddingRight: '16px',
|
|
||||||
paddingTop: '8px',
|
|
||||||
overflow: 'scroll',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const CrashRow = styled(FlexRow)({
|
const StyledFlexColumn = styled(StyledFlexGrowColumn)({
|
||||||
paddingTop: '8px',
|
justifyContent: 'center',
|
||||||
});
|
alignItems: 'center',
|
||||||
|
|
||||||
const CallStack = styled('pre')({
|
|
||||||
fontFamily: 'Monospace',
|
|
||||||
fontSize: '100%',
|
|
||||||
paddingLeft: '8px',
|
|
||||||
maxHeight: '500px',
|
|
||||||
overflow: 'scroll',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export function getNewPersisitedStateFromCrashLog(
|
export function getNewPersisitedStateFromCrashLog(
|
||||||
@@ -258,14 +295,47 @@ function addFileWatcherForiOSCrashLogs(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CrashReporterBar extends Component<CrashReporterBarProps> {
|
||||||
|
render() {
|
||||||
|
const {openLogsCallback} = this.props;
|
||||||
|
return (
|
||||||
|
<Toolbar>
|
||||||
|
<Spacer />
|
||||||
|
<Button
|
||||||
|
disabled={Boolean(!openLogsCallback)}
|
||||||
|
onClick={openLogsCallback}>
|
||||||
|
Open In Logs
|
||||||
|
</Button>
|
||||||
|
</Toolbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HeaderRow extends Component<HeaderRowProps> {
|
||||||
|
render() {
|
||||||
|
const {title, value} = this.props;
|
||||||
|
return (
|
||||||
|
<Padder paddingTop={8} paddingBottom={2}>
|
||||||
|
<Container>
|
||||||
|
<Padder paddingLeft={8}>
|
||||||
|
<FlexRow>
|
||||||
|
<Title>{title}</Title>
|
||||||
|
<Value code={true}>{value}</Value>
|
||||||
|
</FlexRow>
|
||||||
|
</Padder>
|
||||||
|
<Line />
|
||||||
|
</Container>
|
||||||
|
</Padder>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default class CrashReporterPlugin extends FlipperDevicePlugin<
|
export default class CrashReporterPlugin extends FlipperDevicePlugin<
|
||||||
*,
|
*,
|
||||||
*,
|
*,
|
||||||
PersistedState,
|
PersistedState,
|
||||||
> {
|
> {
|
||||||
static defaultPersistedState = {
|
static defaultPersistedState = {crashes: []};
|
||||||
crashes: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
static supportsDevice(device: Device) {
|
static supportsDevice(device: Device) {
|
||||||
return device.os === 'iOS' || device.os === 'Android';
|
return device.os === 'iOS' || device.os === 'Android';
|
||||||
@@ -379,7 +449,7 @@ export default class CrashReporterPlugin extends FlipperDevicePlugin<
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let crash: ?Crash =
|
const currentCrash: ?Crash =
|
||||||
this.props.persistedState.crashes &&
|
this.props.persistedState.crashes &&
|
||||||
this.props.persistedState.crashes.length > 0
|
this.props.persistedState.crashes.length > 0
|
||||||
? this.props.persistedState.crashes[
|
? this.props.persistedState.crashes[
|
||||||
@@ -387,32 +457,41 @@ export default class CrashReporterPlugin extends FlipperDevicePlugin<
|
|||||||
]
|
]
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
let deeplinkedCrash = null;
|
||||||
if (this.props.deepLinkPayload) {
|
if (this.props.deepLinkPayload) {
|
||||||
const id = this.props.deepLinkPayload;
|
const id = this.props.deepLinkPayload;
|
||||||
const index = this.props.persistedState.crashes.findIndex(elem => {
|
const index = this.props.persistedState.crashes.findIndex(elem => {
|
||||||
return elem.notificationID === id;
|
return elem.notificationID === id;
|
||||||
});
|
});
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
crash = this.props.persistedState.crashes[index];
|
deeplinkedCrash = this.props.persistedState.crashes[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const crash = deeplinkedCrash || currentCrash;
|
||||||
if (crash) {
|
if (crash) {
|
||||||
const callstackString = crash.callstack;
|
const callstackString = crash.callstack;
|
||||||
|
|
||||||
|
const children = crash.callstack.split('\n').map(str => {
|
||||||
|
return {message: str};
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<RootColumn>
|
<FlexColumn>
|
||||||
<CrashRow>
|
{this.device.os == 'Android' ? (
|
||||||
<Title>Name</Title>
|
<CrashReporterBar
|
||||||
<Value>{crash.name}</Value>
|
openLogsCallback={() => {
|
||||||
</CrashRow>
|
this.openInLogs(crash.callstack);
|
||||||
<CrashRow>
|
}}
|
||||||
<Title>Reason</Title>
|
/>
|
||||||
<Value>{crash.reason}</Value>
|
) : (
|
||||||
</CrashRow>
|
<CrashReporterBar />
|
||||||
<CrashRow>
|
)}
|
||||||
<Title>CallStack</Title>
|
<ScrollableColumn>
|
||||||
</CrashRow>
|
<HeaderRow title="Name" value={crash.name} />
|
||||||
<CrashRow>
|
<HeaderRow title="Reason" value={crash.reason} />
|
||||||
|
<Padder paddingLeft={8} paddingTop={4} paddingBottom={2}>
|
||||||
|
<Title> Stacktrace </Title>
|
||||||
|
</Padder>
|
||||||
<ContextMenu
|
<ContextMenu
|
||||||
items={[
|
items={[
|
||||||
{
|
{
|
||||||
@@ -422,29 +501,27 @@ export default class CrashReporterPlugin extends FlipperDevicePlugin<
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
]}>
|
]}>
|
||||||
<CallStack>{callstackString}</CallStack>
|
<Line />
|
||||||
|
<StackTrace
|
||||||
|
children={children}
|
||||||
|
isCrash={false}
|
||||||
|
padded={false}
|
||||||
|
backgroundColor={colors.greyStackTraceTint}
|
||||||
|
/>
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
</CrashRow>
|
</ScrollableColumn>
|
||||||
{this.device.os == 'Android' && (
|
</FlexColumn>
|
||||||
<CrashRow>
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
//$FlowFixMe: checked that crash is not undefined
|
|
||||||
this.openInLogs(crash.callstack);
|
|
||||||
}}>
|
|
||||||
Open in Logs
|
|
||||||
</Button>
|
|
||||||
</CrashRow>
|
|
||||||
)}
|
|
||||||
</RootColumn>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<RootColumn>
|
<StyledFlexGrowColumn>
|
||||||
<Title>
|
<CrashReporterBar />
|
||||||
Dedicated space to debug crashes. Look out for crash notifications
|
<StyledFlexColumn>
|
||||||
</Title>
|
<Padder paddingBottom={8}>
|
||||||
</RootColumn>
|
<Title>No Crashes Logged</Title>
|
||||||
|
</Padder>
|
||||||
|
</StyledFlexColumn>
|
||||||
|
</StyledFlexGrowColumn>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ export const colors = {
|
|||||||
purpleTint: '#E8E3F4',
|
purpleTint: '#E8E3F4',
|
||||||
grey: '#88A2AB', // Grey - Debug
|
grey: '#88A2AB', // Grey - Debug
|
||||||
greyTint: '#E7ECEE',
|
greyTint: '#E7ECEE',
|
||||||
|
greyTint2: '#e5e5e5', // Grey - Can be used in demarcation with greyStackTraceTint
|
||||||
|
greyTint3: '#515151', // Grey - Can be used as the color for the title
|
||||||
|
greyStackTraceTint: '#f5f6f8', // Grey - It is used as the background for the stacktrace in crash reporter plugin
|
||||||
cyan: '#4FC9EA', // Cyan - Info
|
cyan: '#4FC9EA', // Cyan - Info
|
||||||
cyanTint: '#DCF4FB', // Cyan - Info
|
cyanTint: '#DCF4FB', // Cyan - Info
|
||||||
// FIG UI Light
|
// FIG UI Light
|
||||||
|
|||||||
Reference in New Issue
Block a user