From 2289d6c0e230662b4bbca8e97df376f3013551d3 Mon Sep 17 00:00:00 2001 From: Andrey Goncharov Date: Tue, 25 Oct 2022 05:31:48 -0700 Subject: [PATCH] Create a partial universal export in case of errors Summary: Design doc: https://docs.google.com/document/d/1HLCFl46RfqG0o1mSt8SWrwf_HMfOCRg_oENioc1rkvQ/edit# Attach what we can to the universal export file if any of the steps time out CHANGELOG: Add a universal debug export button Reviewed By: passy Differential Revision: D40552235 fbshipit-source-id: 775afccacf053fbcf764d1f39e93a89ad20dee0a --- .../src/sandy-chrome/LeftRail.tsx | 8 +- .../flipper-ui-core/src/utils/exportData.tsx | 85 ++++++++++++------- 2 files changed, 55 insertions(+), 38 deletions(-) diff --git a/desktop/flipper-ui-core/src/sandy-chrome/LeftRail.tsx b/desktop/flipper-ui-core/src/sandy-chrome/LeftRail.tsx index a4d542ab3..d42c54990 100644 --- a/desktop/flipper-ui-core/src/sandy-chrome/LeftRail.tsx +++ b/desktop/flipper-ui-core/src/sandy-chrome/LeftRail.tsx @@ -471,9 +471,7 @@ function ExportEverythingEverywhereAllAtOnceButton() {

Exporting Flipper debug files from all devices...

It could take a long time!

Let's count sheep while we wait: {sheepCount++}.

-

- Scream for help if the sheep count reaches 42, but not earlier. -

+

We'll skip it automatically if it exceeds 3 minutes.

, ); }; @@ -491,14 +489,14 @@ function ExportEverythingEverywhereAllAtOnceButton() {

Exporting Flipper state...

It also could take a long time!

This time we could count dinosaurs: {dinosaursCount++}.

-

You already know what to do when the counter reaches 42.

+

We'll skip it automatically if it exceeds 2 minutes.

, ); }; setStateExportMessage(); - const interval = setInterval(setStateExportMessage, 1000); + const interval = setInterval(setStateExportMessage, 2000); return () => clearInterval(interval); } case 'archive': { diff --git a/desktop/flipper-ui-core/src/utils/exportData.tsx b/desktop/flipper-ui-core/src/utils/exportData.tsx index 628b90153..c5dbfd076 100644 --- a/desktop/flipper-ui-core/src/utils/exportData.tsx +++ b/desktop/flipper-ui-core/src/utils/exportData.tsx @@ -8,7 +8,12 @@ */ import * as React from 'react'; -import {getLogger, DeviceDebugFile, DeviceDebugCommand} from 'flipper-common'; +import { + getLogger, + DeviceDebugFile, + DeviceDebugCommand, + timeout, +} from 'flipper-common'; import {Store, MiddlewareAPI} from '../reducers'; import {DeviceExport} from 'flipper-frontend-core'; import {selectedPlugins, State as PluginsState} from '../reducers/plugins'; @@ -643,44 +648,58 @@ export async function exportEverythingEverywhereAllAtOnce( zip.file('flipper_logs.txt', serializedLogs); - // Step 2: Export device logs - onStatusUpdate?.('files'); - const flipperFolderContent = await startDeviceFlipperFolderExport(); + try { + // Step 2: Export device logs + onStatusUpdate?.('files'); + const flipperFolderContent = await startDeviceFlipperFolderExport(); - const deviceFlipperFolder = zip.folder('device_flipper_folder')!; - flipperFolderContent.forEach((deviceDebugItem) => { - const deviceAppFolder = deviceFlipperFolder.folder( - safeFilename(`${deviceDebugItem.serial}__${deviceDebugItem.appId}`), - )!; + const deviceFlipperFolder = zip.folder('device_flipper_folder')!; + flipperFolderContent.forEach((deviceDebugItem) => { + const deviceAppFolder = deviceFlipperFolder.folder( + safeFilename(`${deviceDebugItem.serial}__${deviceDebugItem.appId}`), + )!; - deviceDebugItem.data.forEach((appDebugItem) => { - const appDebugItemIsFile = ( - item: DeviceDebugFile | DeviceDebugCommand, - ): item is DeviceDebugFile => !!(appDebugItem as DeviceDebugFile).path; + deviceDebugItem.data.forEach((appDebugItem) => { + const appDebugItemIsFile = ( + item: DeviceDebugFile | DeviceDebugCommand, + ): item is DeviceDebugFile => !!(appDebugItem as DeviceDebugFile).path; - if (appDebugItemIsFile(appDebugItem)) { - deviceAppFolder.file( - safeFilename(appDebugItem.path), - appDebugItem.data, - ); - } else { - deviceAppFolder.file( - safeFilename(appDebugItem.command), - appDebugItem.result, - ); - } + if (appDebugItemIsFile(appDebugItem)) { + deviceAppFolder.file( + safeFilename(appDebugItem.path), + appDebugItem.data, + ); + } else { + deviceAppFolder.file( + safeFilename(appDebugItem.command), + appDebugItem.result, + ); + } + }); }); - }); + } catch (e) { + console.error( + 'exportEverythingEverywhereAllAtOnce -> failed to export Flipper device debug data', + e, + ); + } - // Step 3: Export Flipper State - onStatusUpdate?.('state'); - const exportablePlugins = getExportablePlugins(store.getState()); - // TODO: no need to put this in the store, - // need to be cleaned up later in combination with SupportForm - store.dispatch(selectedPlugins(exportablePlugins.map(({id}) => id))); - const {serializedString} = await exportStore(store); + try { + // Step 3: Export Flipper State + onStatusUpdate?.('state'); + const exportablePlugins = getExportablePlugins(store.getState()); + // TODO: no need to put this in the store, + // need to be cleaned up later in combination with SupportForm + store.dispatch(selectedPlugins(exportablePlugins.map(({id}) => id))); + const {serializedString} = await timeout(2 * 60 * 1000, exportStore(store)); - zip.file('flipper_export', serializedString); + zip.file('flipper_export', serializedString); + } catch (e) { + console.error( + 'exportEverythingEverywhereAllAtOnce -> failed to export Flipper state', + e, + ); + } onStatusUpdate?.('archive'); const archiveData = await zip.generateAsync({type: 'uint8array'});