From dd3f0fdfeb0160f9cddd56649e2395ec6a667556 Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Mon, 25 Mar 2019 04:50:07 -0700 Subject: [PATCH] Parse Date from the crash and fix the date mismatch in the UI Summary: This diff parses the `Date` from the crash log, so that the `Date` shown on the UI matches with the actual crash log Bug: {F154301489} Added test too Reviewed By: danielbuechele Differential Revision: D14563053 fbshipit-source-id: b9dc7de11d7f17d6c7aa2afe5106b8f85c0a535c --- .../testCrashReporterPlugin.electron.js | 23 +++++++++++++-- src/plugins/crash_reporter/index.js | 28 +++++++++++++++++-- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/plugins/crash_reporter/__tests__/testCrashReporterPlugin.electron.js b/src/plugins/crash_reporter/__tests__/testCrashReporterPlugin.electron.js index 1667c7ca8..56b02556d 100644 --- a/src/plugins/crash_reporter/__tests__/testCrashReporterPlugin.electron.js +++ b/src/plugins/crash_reporter/__tests__/testCrashReporterPlugin.electron.js @@ -64,14 +64,26 @@ afterAll(() => { setCrashReporterPluginID(''); }); -test('test the parsing of the reason for crash when log matches the predefined regex', () => { +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'); + expect(crash.callstack).toEqual(log); + expect(crash.reason).toEqual('SIGSEGV'); + expect(crash.name).toEqual('SIGSEGV'); + expect(crash.date).toEqual(new Date('2019-03-21 12:07:00.861')); +}); + +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'); expect(crash.callstack).toEqual(log); expect(crash.reason).toEqual('SIGSEGV'); expect(crash.name).toEqual('SIGSEGV'); + expect(crash.date).toBeUndefined(); }); + 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'); @@ -87,6 +99,7 @@ test('test the parsing of the reason for crash when log does not match the prede expect(crash.callstack).toEqual(log); expect(crash.reason).toEqual('Cannot figure out the cause'); expect(crash.name).toEqual('Cannot figure out the cause'); + expect(crash.date).toBeUndefined(); }); test('test the parsing of the reason for crash when log is empty', () => { const log = ''; @@ -94,23 +107,27 @@ test('test the parsing of the reason for crash when log is empty', () => { expect(crash.callstack).toEqual(log); expect(crash.reason).toEqual('Cannot figure out the cause'); expect(crash.name).toEqual('Cannot figure out the cause'); + expect(crash.date).toBeUndefined(); }); test('test the parsing of the Android crash log for the proper android crash format', () => { 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, 'Android'); + const date = new Date(); + const crash = parseCrashLog(log, 'Android', date); expect(crash.callstack).toEqual(log); expect(crash.reason).toEqual( 'java.lang.IndexOutOfBoundsException: Index: 190, Size: 0', ); expect(crash.name).toEqual('FATAL EXCEPTION: main'); + expect(crash.date).toEqual(date); }); -test('test the parsing of the Android crash log for the unknown crash format', () => { +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'); expect(crash.callstack).toEqual(log); expect(crash.reason).toEqual('Cannot figure out the cause'); expect(crash.name).toEqual('Cannot figure out the cause'); + expect(crash.date).toBeUndefined(); }); 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 '; diff --git a/src/plugins/crash_reporter/index.js b/src/plugins/crash_reporter/index.js index 81a93c6ce..996e6ac42 100644 --- a/src/plugins/crash_reporter/index.js +++ b/src/plugins/crash_reporter/index.js @@ -66,6 +66,7 @@ export type CrashLog = {| callstack: string, reason: string, name: string, + date: ?Date, |}; export type PersistedState = { @@ -164,12 +165,13 @@ export function getNewPersisitedStateFromCrashLog( persistingPlugin: Class | FlipperPlugin<>>, content: string, os: ?OS, + logDate: ?Date, ): ?PersistedState { const persistedStateReducer = persistingPlugin.persistedStateReducer; if (!os || !persistedStateReducer) { return null; } - const crash = parseCrashLog(content, os); + const crash = parseCrashLog(content, os, logDate); const newPluginState = persistedStateReducer( persistedState, 'crash-report', @@ -185,6 +187,7 @@ export function parseCrashLogAndUpdateState( pluginKey: string, newPluginState: ?PersistedState, ) => void, + logDate: ?Date, ) { const os = store.getState().connections.selectedDevice?.os; if ( @@ -219,6 +222,7 @@ export function parseCrashLogAndUpdateState( persistingPlugin, content, os, + logDate, ); setPersistedState(pluginKey, newPluginState); } @@ -240,7 +244,11 @@ export function shouldShowCrashNotification( return true; } -export function parseCrashLog(content: string, os: OS): CrashLog { +export function parseCrashLog( + content: string, + os: OS, + logDate: ?Date, +): CrashLog { const stubString = 'Cannot figure out the cause'; switch (os) { case 'iOS': { @@ -251,10 +259,24 @@ export function parseCrashLog(content: string, os: OS): CrashLog { const tmp = exceptionRegex.exec(exceptionString); const exception = tmp && tmp[0].length ? tmp[0] : 'Cannot figure out the cause'; + + let date = logDate; + if (!date) { + const dateRegex = /Date\/Time: *[\w\s\.:-]*/; + const dateArr = dateRegex.exec(content); + const dateString = dateArr ? dateArr[0] : ''; + const dateRegex2 = /[\w\s\.:-]*$/; + const tmp1 = dateRegex2.exec(dateString); + const extractedDateString: ?string = + tmp1 && tmp1[0].length ? tmp1[0] : null; + date = extractedDateString ? new Date(extractedDateString) : logDate; + } + const crash = { callstack: content, name: exception, reason: exception, + date, }; return crash; } @@ -281,6 +303,7 @@ export function parseCrashLog(content: string, os: OS): CrashLog { callstack: content, name: name, reason: reason, + date: logDate, }; return crash; } @@ -542,6 +565,7 @@ export default class CrashReporterPlugin extends FlipperDevicePlugin< store, androidLog, setPersistedState, + entry.date, ); } androidLogUnderProcess = false;