Convert to TypeScript
Summary: Converted the Crash Reporter plugin to Typescript while fixing all linting errors Reviewed By: jknoxville Differential Revision: D22571332 fbshipit-source-id: d3092ffc480827b5eb1beb5c3cc91dad6993e267
This commit is contained in:
committed by
Facebook GitHub Bot
parent
9f4f547ef4
commit
c13593bc7e
@@ -12,7 +12,7 @@ import CrashReporterPlugin from '..';
|
||||
import type {PersistedState, Crash} from '..';
|
||||
import {
|
||||
parseCrashLog,
|
||||
getNewPersisitedStateFromCrashLog,
|
||||
getNewPersistedStateFromCrashLog,
|
||||
parsePath,
|
||||
shouldShowCrashNotification,
|
||||
} from '..';
|
||||
@@ -70,7 +70,7 @@ afterAll(() => {
|
||||
test('test the parsing of the date and crash info for the log which matches the predefined regex', () => {
|
||||
const log =
|
||||
'Blaa Blaaa \n Blaa Blaaa \n Exception Type: SIGSEGV \n Blaa Blaa \n Blaa Blaa Date/Time: 2019-03-21 12:07:00.861 +0000 \n Blaa balaaa';
|
||||
const crash = parseCrashLog(log, 'iOS');
|
||||
const crash = parseCrashLog(log, 'iOS', null);
|
||||
expect(crash.callstack).toEqual(log);
|
||||
expect(crash.reason).toEqual('SIGSEGV');
|
||||
expect(crash.name).toEqual('SIGSEGV');
|
||||
@@ -80,7 +80,7 @@ test('test the parsing of the date and crash info for the log which matches the
|
||||
test('test the parsing of the reason for crash when log matches the crash regex, but there is no mention of date', () => {
|
||||
const log =
|
||||
'Blaa Blaaa \n Blaa Blaaa \n Exception Type: SIGSEGV \n Blaa Blaa \n Blaa Blaa';
|
||||
const crash = parseCrashLog(log, 'iOS');
|
||||
const crash = parseCrashLog(log, 'iOS', undefined);
|
||||
expect(crash.callstack).toEqual(log);
|
||||
expect(crash.reason).toEqual('SIGSEGV');
|
||||
expect(crash.name).toEqual('SIGSEGV');
|
||||
@@ -89,7 +89,7 @@ test('test the parsing of the reason for crash when log matches the crash regex,
|
||||
|
||||
test('test the parsing of the crash log when log does not match the predefined regex but is alphanumeric', () => {
|
||||
const log = 'Blaa Blaaa \n Blaa Blaaa \n Blaa Blaaa';
|
||||
const crash = parseCrashLog(log, 'iOS');
|
||||
const crash = parseCrashLog(log, 'iOS', undefined);
|
||||
expect(crash.callstack).toEqual(log);
|
||||
expect(crash.reason).toEqual('Cannot figure out the cause');
|
||||
expect(crash.name).toEqual('Cannot figure out the cause');
|
||||
@@ -98,7 +98,7 @@ test('test the parsing of the crash log when log does not match the predefined r
|
||||
test('test the parsing of the reason for crash when log does not match the predefined regex contains unicode character', () => {
|
||||
const log =
|
||||
'Blaa Blaaa \n Blaa Blaaa \n Exception Type: 🍕🐬 \n Blaa Blaa \n Blaa Blaa';
|
||||
const crash = parseCrashLog(log, 'iOS');
|
||||
const crash = parseCrashLog(log, 'iOS', undefined);
|
||||
expect(crash.callstack).toEqual(log);
|
||||
expect(crash.reason).toEqual('Cannot figure out the cause');
|
||||
expect(crash.name).toEqual('Cannot figure out the cause');
|
||||
@@ -106,7 +106,7 @@ test('test the parsing of the reason for crash when log does not match the prede
|
||||
});
|
||||
test('test the parsing of the reason for crash when log is empty', () => {
|
||||
const log = '';
|
||||
const crash = parseCrashLog(log, 'iOS');
|
||||
const crash = parseCrashLog(log, 'iOS', undefined);
|
||||
expect(crash.callstack).toEqual(log);
|
||||
expect(crash.reason).toEqual('Cannot figure out the cause');
|
||||
expect(crash.name).toEqual('Cannot figure out the cause');
|
||||
@@ -126,7 +126,7 @@ test('test the parsing of the Android crash log for the proper android crash for
|
||||
});
|
||||
test('test the parsing of the Android crash log for the unknown crash format and no date', () => {
|
||||
const log = 'Blaa Blaa Blaa';
|
||||
const crash = parseCrashLog(log, 'Android');
|
||||
const crash = parseCrashLog(log, 'Android', undefined);
|
||||
expect(crash.callstack).toEqual(log);
|
||||
expect(crash.reason).toEqual('Cannot figure out the cause');
|
||||
expect(crash.name).toEqual('Cannot figure out the cause');
|
||||
@@ -134,7 +134,7 @@ test('test the parsing of the Android crash log for the unknown crash format and
|
||||
});
|
||||
test('test the parsing of the Android crash log for the partial format matching the crash format', () => {
|
||||
const log = 'First Line Break \n Blaa Blaa \n Blaa Blaa ';
|
||||
const crash = parseCrashLog(log, 'Android');
|
||||
const crash = parseCrashLog(log, 'Android', null);
|
||||
expect(crash.callstack).toEqual(log);
|
||||
expect(crash.reason).toEqual('Cannot figure out the cause');
|
||||
expect(crash.name).toEqual('First Line Break ');
|
||||
@@ -142,26 +142,26 @@ test('test the parsing of the Android crash log for the partial format matching
|
||||
test('test the parsing of the Android crash log with os being iOS', () => {
|
||||
const log =
|
||||
'FATAL EXCEPTION: main\nProcess: com.facebook.flipper.sample, PID: 27026\njava.lang.IndexOutOfBoundsException: Index: 190, Size: 0\n\tat java.util.ArrayList.get(ArrayList.java:437)\n\tat com.facebook.flipper.sample.RootComponentSpec.hitGetRequest(RootComponentSpec.java:72)\n\tat com.facebook.flipper.sample.RootComponent.hitGetRequest(RootComponent.java:46)\n';
|
||||
const crash = parseCrashLog(log, 'iOS');
|
||||
const crash = parseCrashLog(log, 'iOS', null);
|
||||
expect(crash.callstack).toEqual(log);
|
||||
expect(crash.reason).toEqual('Cannot figure out the cause');
|
||||
expect(crash.name).toEqual('Cannot figure out the cause');
|
||||
});
|
||||
test('test the getter of pluginKey with proper input', () => {
|
||||
const device = new BaseDevice('serial', 'emulator', 'test device');
|
||||
const device = new BaseDevice('serial', 'emulator', 'test device', 'iOS');
|
||||
const pluginKey = getPluginKey(null, device, 'CrashReporter');
|
||||
expect(pluginKey).toEqual('serial#CrashReporter');
|
||||
});
|
||||
test('test the getter of pluginKey with undefined input', () => {
|
||||
const pluginKey = getPluginKey(null, undefined, 'CrashReporter');
|
||||
const pluginKey = getPluginKey(null, null, 'CrashReporter');
|
||||
expect(pluginKey).toEqual('unknown#CrashReporter');
|
||||
});
|
||||
test('test the getter of pluginKey with defined selected app', () => {
|
||||
const pluginKey = getPluginKey('selectedApp', undefined, 'CrashReporter');
|
||||
const pluginKey = getPluginKey('selectedApp', null, 'CrashReporter');
|
||||
expect(pluginKey).toEqual('selectedApp#CrashReporter');
|
||||
});
|
||||
test('test the getter of pluginKey with defined selected app and defined base device', () => {
|
||||
const device = new BaseDevice('serial', 'emulator', 'test device');
|
||||
const device = new BaseDevice('serial', 'emulator', 'test device', 'iOS');
|
||||
const pluginKey = getPluginKey('selectedApp', device, 'CrashReporter');
|
||||
expect(pluginKey).toEqual('selectedApp#CrashReporter');
|
||||
});
|
||||
@@ -177,12 +177,12 @@ test('test getPersistedState for non-empty defaultPersistedState and undefined p
|
||||
const crash = getCrash(0, 'callstack', 'crash0', 'crash0');
|
||||
setDefaultPersistedState({crashes: [crash]});
|
||||
const pluginStates = {};
|
||||
const perisistedState = getPersistedState(
|
||||
const persistedState = getPersistedState(
|
||||
getPluginKey(null, null, CrashReporterPlugin.id),
|
||||
CrashReporterPlugin,
|
||||
pluginStates,
|
||||
);
|
||||
expect(perisistedState).toEqual({crashes: [crash]});
|
||||
expect(persistedState).toEqual({crashes: [crash]});
|
||||
});
|
||||
test('test getPersistedState for non-empty defaultPersistedState and defined pluginState', () => {
|
||||
const crash = getCrash(0, 'callstack', 'crash0', 'crash0');
|
||||
@@ -190,40 +190,42 @@ test('test getPersistedState for non-empty defaultPersistedState and defined plu
|
||||
setDefaultPersistedState({crashes: [crash]});
|
||||
const pluginStateCrash = getCrash(1, 'callstack', 'crash1', 'crash1');
|
||||
const pluginStates = {'unknown#CrashReporter': {crashes: [pluginStateCrash]}};
|
||||
const perisistedState = getPersistedState(
|
||||
const persistedState = getPersistedState(
|
||||
pluginKey,
|
||||
CrashReporterPlugin,
|
||||
pluginStates,
|
||||
);
|
||||
expect(perisistedState).toEqual({crashes: [pluginStateCrash]});
|
||||
expect(persistedState).toEqual({crashes: [pluginStateCrash]});
|
||||
});
|
||||
test('test getNewPersisitedStateFromCrashLog for non-empty defaultPersistedState and defined pluginState', () => {
|
||||
test('test getNewPersistedStateFromCrashLog for non-empty defaultPersistedState and defined pluginState', () => {
|
||||
const crash = getCrash(0, 'callstack', 'crash0', 'crash0');
|
||||
const pluginKey = getPluginKey(null, null, CrashReporterPlugin.id);
|
||||
setDefaultPersistedState({crashes: [crash]});
|
||||
const pluginStateCrash = getCrash(1, 'callstack', 'crash1', 'crash1');
|
||||
const pluginStates = {'unknown#CrashReporter': {crashes: [pluginStateCrash]}};
|
||||
const perisistedState = getPersistedState(
|
||||
const persistedState = getPersistedState(
|
||||
pluginKey,
|
||||
CrashReporterPlugin,
|
||||
pluginStates,
|
||||
);
|
||||
const content =
|
||||
'Blaa Blaaa \n Blaa Blaaa \n Exception Type: SIGSEGV \n Blaa Blaa \n Blaa Blaa';
|
||||
expect(perisistedState).toBeDefined();
|
||||
const {crashes} = perisistedState;
|
||||
expect(persistedState).toBeDefined();
|
||||
const definedState = persistedState as PersistedState;
|
||||
const {crashes} = definedState;
|
||||
expect(crashes).toBeDefined();
|
||||
expect(crashes.length).toEqual(1);
|
||||
expect(crashes[0]).toEqual(pluginStateCrash);
|
||||
const newPersistedState = getNewPersisitedStateFromCrashLog(
|
||||
perisistedState,
|
||||
const newPersistedState = getNewPersistedStateFromCrashLog(
|
||||
definedState,
|
||||
CrashReporterPlugin,
|
||||
content,
|
||||
'iOS',
|
||||
null,
|
||||
);
|
||||
expect(newPersistedState).toBeDefined();
|
||||
// $FlowFixMe: Checked if perisistedState is defined or not
|
||||
const newPersistedStateCrashes = newPersistedState.crashes;
|
||||
const newDefinedState = newPersistedState as PersistedState;
|
||||
const newPersistedStateCrashes = newDefinedState.crashes;
|
||||
expect(newPersistedStateCrashes).toBeDefined();
|
||||
expect(newPersistedStateCrashes.length).toEqual(2);
|
||||
assertCrash(newPersistedStateCrashes[0], pluginStateCrash);
|
||||
@@ -232,34 +234,35 @@ test('test getNewPersisitedStateFromCrashLog for non-empty defaultPersistedState
|
||||
getCrash(1, content, 'SIGSEGV', 'SIGSEGV'),
|
||||
);
|
||||
});
|
||||
test('test getNewPersisitedStateFromCrashLog for non-empty defaultPersistedState and undefined pluginState', () => {
|
||||
test('test getNewPersistedStateFromCrashLog for non-empty defaultPersistedState and undefined pluginState', () => {
|
||||
setNotificationID(0);
|
||||
const crash = getCrash(0, 'callstack', 'crash0', 'crash0');
|
||||
const pluginKey = getPluginKey(null, null, CrashReporterPlugin.id);
|
||||
setDefaultPersistedState({crashes: [crash]});
|
||||
const pluginStates = {};
|
||||
const perisistedState = getPersistedState(
|
||||
const persistedState = getPersistedState(
|
||||
pluginKey,
|
||||
CrashReporterPlugin,
|
||||
pluginStates,
|
||||
);
|
||||
const content = 'Blaa Blaaa \n Blaa Blaaa \n Exception Type: SIGSEGV';
|
||||
expect(perisistedState).toEqual({crashes: [crash]});
|
||||
const newPersistedState = getNewPersisitedStateFromCrashLog(
|
||||
perisistedState,
|
||||
expect(persistedState).toEqual({crashes: [crash]});
|
||||
const newPersistedState = getNewPersistedStateFromCrashLog(
|
||||
persistedState as PersistedState,
|
||||
CrashReporterPlugin,
|
||||
content,
|
||||
'iOS',
|
||||
null,
|
||||
);
|
||||
expect(newPersistedState).toBeDefined();
|
||||
// $FlowFixMe: Checked if perisistedState is defined or not
|
||||
const {crashes} = newPersistedState;
|
||||
const {crashes} = newPersistedState as PersistedState;
|
||||
expect(crashes).toBeDefined();
|
||||
expect(crashes.length).toEqual(2);
|
||||
assertCrash(crashes[0], crash);
|
||||
assertCrash(crashes[1], getCrash(1, content, 'SIGSEGV', 'SIGSEGV'));
|
||||
});
|
||||
test('test getNewPersisitedStateFromCrashLog for non-empty defaultPersistedState and defined pluginState and improper crash log', () => {
|
||||
test('test getNewPersistedStateFromCrashLog for non-empty defaultPersistedState and defined pluginState and improper crash log', () => {
|
||||
setNotificationID(0);
|
||||
const crash = getCrash(0, 'callstack', 'crash0', 'crash0');
|
||||
const pluginKey = getPluginKey(null, null, CrashReporterPlugin.id);
|
||||
@@ -273,15 +276,16 @@ test('test getNewPersisitedStateFromCrashLog for non-empty defaultPersistedState
|
||||
);
|
||||
const content = 'Blaa Blaaa \n Blaa Blaaa';
|
||||
expect(perisistedState).toEqual({crashes: [pluginStateCrash]});
|
||||
const newPersistedState = getNewPersisitedStateFromCrashLog(
|
||||
perisistedState,
|
||||
const newPersistedState = getNewPersistedStateFromCrashLog(
|
||||
perisistedState as PersistedState,
|
||||
CrashReporterPlugin,
|
||||
content,
|
||||
'iOS',
|
||||
null,
|
||||
);
|
||||
expect(newPersistedState).toBeDefined();
|
||||
// $FlowFixMe: Checked if perisistedState is defined or not
|
||||
const {crashes} = newPersistedState;
|
||||
const {crashes} = newPersistedState as PersistedState;
|
||||
expect(crashes).toBeDefined();
|
||||
expect(crashes.length).toEqual(2);
|
||||
assertCrash(crashes[0], pluginStateCrash);
|
||||
@@ -295,23 +299,25 @@ test('test getNewPersisitedStateFromCrashLog for non-empty defaultPersistedState
|
||||
),
|
||||
);
|
||||
});
|
||||
test('test getNewPersisitedStateFromCrashLog when os is undefined', () => {
|
||||
test('test getNewPersistedStateFromCrashLog when os is undefined', () => {
|
||||
setNotificationID(0);
|
||||
const crash = getCrash(0, 'callstack', 'crash0', 'crash0');
|
||||
const pluginKey = getPluginKey(null, null, CrashReporterPlugin.id);
|
||||
setDefaultPersistedState({crashes: [crash]});
|
||||
const pluginStateCrash = getCrash(1, 'callstack', 'crash1', 'crash1');
|
||||
const pluginStates = {'unknown#CrashReporter': {crashes: [pluginStateCrash]}};
|
||||
const perisistedState = getPersistedState(
|
||||
const persistedState = getPersistedState(
|
||||
pluginKey,
|
||||
CrashReporterPlugin,
|
||||
pluginStates,
|
||||
);
|
||||
const content = 'Blaa Blaaa \n Blaa Blaaa';
|
||||
const newPersistedState = getNewPersisitedStateFromCrashLog(
|
||||
perisistedState,
|
||||
const newPersistedState = getNewPersistedStateFromCrashLog(
|
||||
persistedState as PersistedState,
|
||||
CrashReporterPlugin,
|
||||
content,
|
||||
undefined,
|
||||
null,
|
||||
);
|
||||
expect(newPersistedState).toEqual(null);
|
||||
});
|
||||
@@ -347,22 +353,44 @@ test('test parsing of path when a regex is not present', () => {
|
||||
expect(id).toEqual(null);
|
||||
});
|
||||
test('test shouldShowCrashNotification function for all correct inputs', () => {
|
||||
const device = new BaseDevice('TH1S-15DEV1CE-1D', 'emulator', 'test device');
|
||||
const device = new BaseDevice(
|
||||
'TH1S-15DEV1CE-1D',
|
||||
'emulator',
|
||||
'test device',
|
||||
'iOS',
|
||||
);
|
||||
const content =
|
||||
'Blaa Blaaa \n Blaa Blaaa \n Path: path/to/simulator/TH1S-15DEV1CE-1D/App Name.app/App Name \n Blaa Blaa \n Blaa Blaa';
|
||||
const shouldShowNotification = shouldShowCrashNotification(device, content);
|
||||
const shouldShowNotification = shouldShowCrashNotification(
|
||||
device,
|
||||
content,
|
||||
'iOS',
|
||||
);
|
||||
expect(shouldShowNotification).toEqual(true);
|
||||
});
|
||||
test('test shouldShowCrashNotification function for all correct inputs but incorrect id', () => {
|
||||
const device = new BaseDevice('TH1S-15DEV1CE-1D', 'emulator', 'test device');
|
||||
const device = new BaseDevice(
|
||||
'TH1S-15DEV1CE-1D',
|
||||
'emulator',
|
||||
'test device',
|
||||
'iOS',
|
||||
);
|
||||
const content =
|
||||
'Blaa Blaaa \n Blaa Blaaa \n Path: path/to/simulator/TH1S-1598DEV1CE-2D/App Name.app/App Name \n Blaa Blaa \n Blaa Blaa';
|
||||
const shouldShowNotification = shouldShowCrashNotification(device, content);
|
||||
const shouldShowNotification = shouldShowCrashNotification(
|
||||
device,
|
||||
content,
|
||||
'iOS',
|
||||
);
|
||||
expect(shouldShowNotification).toEqual(false);
|
||||
});
|
||||
test('test shouldShowCrashNotification function for undefined device', () => {
|
||||
const content =
|
||||
'Blaa Blaaa \n Blaa Blaaa \n Path: path/to/simulator/TH1S-1598DEV1CE-2D/App Name.app/App Name \n Blaa Blaa \n Blaa Blaa';
|
||||
const shouldShowNotification = shouldShowCrashNotification(null, content);
|
||||
const shouldShowNotification = shouldShowCrashNotification(
|
||||
null,
|
||||
content,
|
||||
'iOS',
|
||||
);
|
||||
expect(shouldShowNotification).toEqual(false);
|
||||
});
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
FlipperBasePlugin,
|
||||
FlipperDevicePlugin,
|
||||
Device,
|
||||
View,
|
||||
@@ -37,57 +38,63 @@ import path from 'path';
|
||||
import {promisify} from 'util';
|
||||
import type {Notification} from 'flipper';
|
||||
import type {Store, DeviceLogEntry, OS, Props} from 'flipper';
|
||||
import React from 'react';
|
||||
import {Component} from 'react';
|
||||
|
||||
type Maybe<T> = T | null | undefined;
|
||||
|
||||
type HeaderRowProps = {
|
||||
title: string,
|
||||
value: string,
|
||||
title: string;
|
||||
value: string;
|
||||
};
|
||||
type openLogsCallbackType = () => void;
|
||||
|
||||
type CrashReporterBarProps = {|
|
||||
openLogsCallback?: openLogsCallbackType,
|
||||
crashSelector: CrashSelectorProps,
|
||||
|};
|
||||
type CrashReporterBarProps = {
|
||||
openLogsCallback?: openLogsCallbackType;
|
||||
crashSelector: CrashSelectorProps;
|
||||
};
|
||||
|
||||
type CrashSelectorProps = {|
|
||||
crashes: ?{[key: string]: string},
|
||||
orderedIDs: ?Array<string>,
|
||||
selectedCrashID: ?string,
|
||||
onCrashChange: ?(string) => void,
|
||||
|};
|
||||
type CrashSelectorProps = {
|
||||
crashes?: {[key: string]: string};
|
||||
orderedIDs?: Array<string>;
|
||||
selectedCrashID?: string;
|
||||
onCrashChange: (name: Maybe<string>) => void;
|
||||
};
|
||||
|
||||
export type Crash = {|
|
||||
notificationID: string,
|
||||
callstack: ?string,
|
||||
reason: string,
|
||||
name: string,
|
||||
date: Date,
|
||||
|};
|
||||
export type Crash = {
|
||||
notificationID: string;
|
||||
callstack?: string;
|
||||
reason: string;
|
||||
name: string;
|
||||
date: Date;
|
||||
};
|
||||
|
||||
export type CrashLog = {|
|
||||
callstack: string,
|
||||
reason: string,
|
||||
name: string,
|
||||
date: ?Date,
|
||||
|};
|
||||
export type CrashLog = {
|
||||
callstack: string;
|
||||
reason: string;
|
||||
name: string;
|
||||
date: Maybe<Date>;
|
||||
};
|
||||
|
||||
export type PersistedState = {
|
||||
crashes: Array<Crash>,
|
||||
crashes: Array<Crash>;
|
||||
};
|
||||
|
||||
type State = {
|
||||
crash: ?Crash,
|
||||
crash?: Crash;
|
||||
};
|
||||
|
||||
const Padder = styled.div(
|
||||
({paddingLeft, paddingRight, paddingBottom, paddingTop}) => ({
|
||||
const Padder = styled.div<{
|
||||
paddingLeft?: number;
|
||||
paddingRight?: number;
|
||||
paddingBottom?: number;
|
||||
paddingTop?: number;
|
||||
}>(({paddingLeft, paddingRight, paddingBottom, paddingTop}) => ({
|
||||
paddingLeft: paddingLeft || 0,
|
||||
paddingRight: paddingRight || 0,
|
||||
paddingBottom: paddingBottom || 0,
|
||||
paddingTop: paddingTop || 0,
|
||||
}),
|
||||
);
|
||||
}));
|
||||
|
||||
const Title = styled(Text)({
|
||||
fontWeight: 'bold',
|
||||
@@ -183,13 +190,13 @@ const StackTraceContainer = styled(FlexColumn)({
|
||||
|
||||
const UNKNOWN_CRASH_REASON = 'Cannot figure out the cause';
|
||||
|
||||
export function getNewPersisitedStateFromCrashLog(
|
||||
persistedState: ?PersistedState,
|
||||
persistingPlugin: Class<FlipperDevicePlugin<> | FlipperPlugin<>>,
|
||||
export function getNewPersistedStateFromCrashLog(
|
||||
persistedState: Maybe<PersistedState>,
|
||||
persistingPlugin: typeof FlipperBasePlugin,
|
||||
content: string,
|
||||
os: ?OS,
|
||||
logDate: ?Date,
|
||||
): ?PersistedState {
|
||||
os: Maybe<OS>,
|
||||
logDate: Maybe<Date>,
|
||||
): Maybe<PersistedState> {
|
||||
const persistedStateReducer = persistingPlugin.persistedStateReducer;
|
||||
if (!os || !persistedStateReducer) {
|
||||
return null;
|
||||
@@ -208,9 +215,9 @@ export function parseCrashLogAndUpdateState(
|
||||
content: string,
|
||||
setPersistedState: (
|
||||
pluginKey: string,
|
||||
newPluginState: ?PersistedState,
|
||||
newPluginState: Maybe<PersistedState>,
|
||||
) => void,
|
||||
logDate: ?Date,
|
||||
logDate: Maybe<Date>,
|
||||
) {
|
||||
const os = store.getState().connections.selectedDevice?.os;
|
||||
if (
|
||||
@@ -228,9 +235,11 @@ export function parseCrashLogAndUpdateState(
|
||||
store.getState().connections.selectedDevice,
|
||||
pluginID,
|
||||
);
|
||||
const persistingPlugin: ?Class<
|
||||
FlipperDevicePlugin<> | FlipperPlugin<>,
|
||||
> = store.getState().plugins.devicePlugins.get(CrashReporterPlugin.id);
|
||||
const persistingPlugin:
|
||||
| typeof FlipperBasePlugin
|
||||
| undefined = store
|
||||
.getState()
|
||||
.plugins.devicePlugins.get(CrashReporterPlugin.id);
|
||||
if (!persistingPlugin) {
|
||||
return;
|
||||
}
|
||||
@@ -240,8 +249,11 @@ export function parseCrashLogAndUpdateState(
|
||||
persistingPlugin,
|
||||
pluginStates,
|
||||
);
|
||||
const newPluginState = getNewPersisitedStateFromCrashLog(
|
||||
persistedState,
|
||||
if (!persistedState) {
|
||||
return;
|
||||
}
|
||||
const newPluginState = getNewPersistedStateFromCrashLog(
|
||||
persistedState as PersistedState,
|
||||
persistingPlugin,
|
||||
content,
|
||||
os,
|
||||
@@ -251,9 +263,9 @@ export function parseCrashLogAndUpdateState(
|
||||
}
|
||||
|
||||
export function shouldShowCrashNotification(
|
||||
baseDevice: ?BaseDevice,
|
||||
baseDevice: Maybe<BaseDevice>,
|
||||
content: string,
|
||||
os: ?OS,
|
||||
os: Maybe<OS>,
|
||||
): boolean {
|
||||
if (os && os === 'Android') {
|
||||
return true;
|
||||
@@ -270,7 +282,7 @@ export function shouldShowCrashNotification(
|
||||
export function parseCrashLog(
|
||||
content: string,
|
||||
os: OS,
|
||||
logDate: ?Date,
|
||||
logDate: Maybe<Date>,
|
||||
): CrashLog {
|
||||
const fallbackReason = UNKNOWN_CRASH_REASON;
|
||||
switch (os) {
|
||||
@@ -289,12 +301,12 @@ export function parseCrashLog(
|
||||
const dateString = dateArr ? dateArr[0] : '';
|
||||
const dateRegex2 = /[\w\s\.:-]*$/;
|
||||
const tmp1 = dateRegex2.exec(dateString);
|
||||
const extractedDateString: ?string =
|
||||
const extractedDateString: Maybe<string> =
|
||||
tmp1 && tmp1[0].length ? tmp1[0] : null;
|
||||
date = extractedDateString ? new Date(extractedDateString) : logDate;
|
||||
}
|
||||
|
||||
const crash = {
|
||||
const crash: CrashLog = {
|
||||
callstack: content,
|
||||
name: exception,
|
||||
reason: exception,
|
||||
@@ -314,14 +326,15 @@ export function parseCrashLog(
|
||||
if (remainingString[remainingString.length - 1] === '\n') {
|
||||
remainingString = remainingString.slice(0, -1);
|
||||
}
|
||||
const reason =
|
||||
const reasonText =
|
||||
remainingString.length > 0
|
||||
? remainingString.split('\n').pop()
|
||||
: fallbackReason;
|
||||
const reason = reasonText ? reasonText : fallbackReason;
|
||||
if (name[name.length - 1] === '\n') {
|
||||
name = name.slice(0, -1);
|
||||
}
|
||||
const crash = {
|
||||
const crash: CrashLog = {
|
||||
callstack: content,
|
||||
name: name,
|
||||
reason: reason,
|
||||
@@ -343,7 +356,7 @@ function truncate(baseString: string, numOfChars: number): string {
|
||||
return truncated_string + '\u2026';
|
||||
}
|
||||
|
||||
export function parsePath(content: string): ?string {
|
||||
export function parsePath(content: string): Maybe<string> {
|
||||
const regex = /Path: *[\w\-\/\.\t\ \_\%]*\n/;
|
||||
const arr = regex.exec(content);
|
||||
if (!arr || arr.length <= 0) {
|
||||
@@ -363,7 +376,7 @@ function addFileWatcherForiOSCrashLogs(
|
||||
store: Store,
|
||||
setPersistedState: (
|
||||
pluginKey: string,
|
||||
newPluginState: ?PersistedState,
|
||||
newPluginState: Maybe<PersistedState>,
|
||||
) => void,
|
||||
) {
|
||||
const dir = path.join(os.homedir(), 'Library', 'Logs', 'DiagnosticReports');
|
||||
@@ -395,6 +408,7 @@ function addFileWatcherForiOSCrashLogs(
|
||||
store,
|
||||
util.format(data),
|
||||
setPersistedState,
|
||||
null,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -412,8 +426,8 @@ class CrashSelector extends Component<CrashSelectorProps> {
|
||||
disabled={Boolean(!orderedIDs || orderedIDs.length <= 1)}
|
||||
compact={true}
|
||||
onClick={() => {
|
||||
if (onCrashChange && orderedIDs) {
|
||||
const index = orderedIDs.indexOf(selectedCrashID);
|
||||
if (onCrashChange && orderedIDs && selectedCrashID) {
|
||||
const index = orderedIDs.indexOf(selectedCrashID as string);
|
||||
const nextIndex =
|
||||
index < 1 ? orderedIDs.length - 1 : index - 1;
|
||||
const nextID = orderedIDs[nextIndex];
|
||||
@@ -430,8 +444,8 @@ class CrashSelector extends Component<CrashSelectorProps> {
|
||||
disabled={Boolean(!orderedIDs || orderedIDs.length <= 1)}
|
||||
compact={true}
|
||||
onClick={() => {
|
||||
if (onCrashChange && orderedIDs) {
|
||||
const index = orderedIDs.indexOf(selectedCrashID);
|
||||
if (onCrashChange && orderedIDs && selectedCrashID) {
|
||||
const index = orderedIDs.indexOf(selectedCrashID as string);
|
||||
const nextIndex =
|
||||
index >= orderedIDs.length - 1 ? 0 : index + 1;
|
||||
const nextID = orderedIDs[nextIndex];
|
||||
@@ -506,7 +520,7 @@ class HeaderRow extends Component<HeaderRowProps> {
|
||||
}
|
||||
|
||||
type StackTraceComponentProps = {
|
||||
stacktrace: string,
|
||||
stacktrace: string;
|
||||
};
|
||||
|
||||
class StackTraceComponent extends Component<StackTraceComponentProps> {
|
||||
@@ -525,10 +539,12 @@ class StackTraceComponent extends Component<StackTraceComponentProps> {
|
||||
|
||||
export default class CrashReporterPlugin extends FlipperDevicePlugin<
|
||||
State,
|
||||
void,
|
||||
PersistedState,
|
||||
any,
|
||||
PersistedState
|
||||
> {
|
||||
static defaultPersistedState = {crashes: []};
|
||||
static defaultPersistedState: PersistedState = {
|
||||
crashes: [],
|
||||
};
|
||||
|
||||
static supportsDevice(device: Device) {
|
||||
return (
|
||||
@@ -544,7 +560,7 @@ export default class CrashReporterPlugin extends FlipperDevicePlugin<
|
||||
static persistedStateReducer = (
|
||||
persistedState: PersistedState,
|
||||
method: string,
|
||||
payload: Object,
|
||||
payload: CrashLog | Crash,
|
||||
): PersistedState => {
|
||||
if (method === 'crash-report' || method === 'flipper-crash-report') {
|
||||
CrashReporterPlugin.notificationID++;
|
||||
@@ -615,7 +631,7 @@ export default class CrashReporterPlugin extends FlipperDevicePlugin<
|
||||
baseDevice: BaseDevice,
|
||||
setPersistedState: (
|
||||
pluginKey: string,
|
||||
newPluginState: ?PersistedState,
|
||||
newPluginState: Maybe<PersistedState>,
|
||||
) => void,
|
||||
): void => {
|
||||
if (baseDevice.os.includes('iOS')) {
|
||||
@@ -627,12 +643,12 @@ export default class CrashReporterPlugin extends FlipperDevicePlugin<
|
||||
date: Date,
|
||||
setPersistedState: (
|
||||
pluginKey: string,
|
||||
newPluginState: ?PersistedState,
|
||||
newPluginState: Maybe<PersistedState>,
|
||||
) => void,
|
||||
) {
|
||||
let androidLog: string = '';
|
||||
let androidLogUnderProcess = false;
|
||||
let timer = null;
|
||||
let timer: Maybe<NodeJS.Timeout> = null;
|
||||
baseDevice.addLogListener((entry: DeviceLogEntry) => {
|
||||
if (shouldParseAndroidLog(entry, referenceDate)) {
|
||||
if (androidLogUnderProcess) {
|
||||
@@ -669,7 +685,7 @@ export default class CrashReporterPlugin extends FlipperDevicePlugin<
|
||||
constructor(props: Props<PersistedState>) {
|
||||
// Required step: always call the parent class' constructor
|
||||
super(props);
|
||||
let crash: ?Crash = null;
|
||||
let crash: Crash | undefined = undefined;
|
||||
if (
|
||||
this.props.persistedState.crashes &&
|
||||
this.props.persistedState.crashes.length > 0
|
||||
@@ -679,7 +695,7 @@ export default class CrashReporterPlugin extends FlipperDevicePlugin<
|
||||
];
|
||||
}
|
||||
|
||||
let deeplinkedCrash = null;
|
||||
let deeplinkedCrash: Crash | undefined = undefined;
|
||||
if (this.props.deepLinkPayload) {
|
||||
const id = this.props.deepLinkPayload;
|
||||
const index = this.props.persistedState.crashes.findIndex((elem) => {
|
||||
@@ -720,7 +736,7 @@ export default class CrashReporterPlugin extends FlipperDevicePlugin<
|
||||
(persistedCrash) => persistedCrash.notificationID,
|
||||
);
|
||||
const selectedCrashID = crash.notificationID;
|
||||
const onCrashChange = (id) => {
|
||||
const onCrashChange = (id: Maybe<string>) => {
|
||||
const newSelectedCrash = crashes.find(
|
||||
(element) => element.notificationID === id,
|
||||
);
|
||||
@@ -784,10 +800,10 @@ export default class CrashReporterPlugin extends FlipperDevicePlugin<
|
||||
);
|
||||
}
|
||||
const crashSelector = {
|
||||
crashes: null,
|
||||
orderedIDs: null,
|
||||
selectedCrashID: null,
|
||||
onCrashChange: null,
|
||||
crashes: undefined,
|
||||
orderedIDs: undefined,
|
||||
selectedCrashID: undefined,
|
||||
onCrashChange: () => void {},
|
||||
};
|
||||
return (
|
||||
<StyledFlexGrowColumn>
|
||||
@@ -5,7 +5,7 @@
|
||||
"version": "0.50.0",
|
||||
"description": "A plugin which will display a crash",
|
||||
"main": "dist/bundle.js",
|
||||
"flipperBundlerEntry": "index.js",
|
||||
"flipperBundlerEntry": "index.tsx",
|
||||
"repository": "https://github.com/facebook/flipper",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
17
desktop/plugins/crash_reporter/unicode-substring.d.tsx
Normal file
17
desktop/plugins/crash_reporter/unicode-substring.d.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
declare module 'unicode-substring' {
|
||||
const unicodeSubstring: (
|
||||
string: string,
|
||||
start: number,
|
||||
end: number,
|
||||
) => string;
|
||||
export default unicodeSubstring;
|
||||
}
|
||||
Reference in New Issue
Block a user