Improve error handling for iOSDevices

Summary:
Adding context everywhere as naked messages are hard to track down
and making common errors like missing Xcode license agreements
a warning + error popup instead.

Changelog: Reduce spamminess of iOS connection warnings

Reviewed By: mweststrate

Differential Revision: D26370235

fbshipit-source-id: b283d297479c2bf76a11b5a3f96a59fad70a4a67
This commit is contained in:
Pascal Hartig
2021-02-11 05:06:28 -08:00
committed by Facebook GitHub Bot
parent 8d5f136a34
commit 92f3ab8ff4
2 changed files with 23 additions and 10 deletions

View File

@@ -94,7 +94,7 @@ if (typeof window !== 'undefined') {
async function queryDevices(store: Store, logger: Logger): Promise<any> {
return Promise.all([
checkXcodeVersionMismatch(store),
getSimulators(true).then((devices) => {
getSimulators(store, true).then((devices) => {
processDevices(store, logger, devices, 'emulator');
}),
getActiveDevices(store.getState().settingsState.idbPath).then(
@@ -163,6 +163,7 @@ function getDeviceSetPath() {
}
export function getSimulators(
store: Store,
bootedOnly: boolean,
): Promise<Array<IOSDeviceParams>> {
return promisify(execFile)(
@@ -188,8 +189,16 @@ export function getSimulators(
} as IOSDeviceParams;
});
})
.catch((e) => {
console.error(e);
.catch((e: Error) => {
console.warn('Failed to query simulators:', e);
if (e.message.includes('Xcode license agreements')) {
store.dispatch(
addErrorNotification(
'Xcode license requires approval',
'The Xcode license agreement has changed. You need to either open Xcode and agree to the terms or run `sudo xcodebuild -license` in a Terminal to allow simulators to work with Flipper.',
),
);
}
return Promise.resolve([]);
});
}
@@ -205,7 +214,7 @@ export async function launchSimulator(udid: string): Promise<any> {
function getActiveDevices(idbPath: string): Promise<Array<IOSDeviceParams>> {
return iosUtil.targets(idbPath).catch((e) => {
console.error(e.message);
console.error('Failed to get active iOS devices:', e.message);
return [];
});
}
@@ -218,7 +227,7 @@ function queryDevicesForever(store: Store, logger: Logger) {
setTimeout(() => queryDevicesForever(store, logger), 3000);
})
.catch((err) => {
console.error(err);
console.warn('Failed to continuously query devices:', err);
});
}
@@ -246,7 +255,7 @@ async function checkXcodeVersionMismatch(store: Store) {
}
}
} catch (e) {
console.error(e);
console.error('Failed to determine Xcode version:', e);
}
}
async function isXcodeDetected(): Promise<boolean> {
@@ -259,7 +268,7 @@ export async function getActiveDevicesAndSimulators(
store: Store,
): Promise<Array<IOSDevice>> {
const activeDevices: Array<Array<IOSDeviceParams>> = await Promise.all([
getSimulators(true),
getSimulators(store, true),
getActiveDevices(store.getState().settingsState.idbPath),
]);
const allDevices = activeDevices[0].concat(activeDevices[1]);

View File

@@ -33,7 +33,10 @@ const COLD_BOOT = 'cold-boot';
export function showEmulatorLauncher(store: Store) {
renderReactRoot((unmount) => (
<Provider store={store}>
<LaunchEmulatorDialog onClose={unmount} getSimulators={getSimulators} />
<LaunchEmulatorDialog
onClose={unmount}
getSimulators={getSimulators.bind(store)}
/>
</Provider>
));
}
@@ -56,11 +59,12 @@ export const LaunchEmulatorDialog = withTrackingScope(
);
const [iosEmulators, setIosEmulators] = useState<IOSDeviceParams[]>([]);
const store = useStore();
useEffect(() => {
if (!iosEnabled) {
return;
}
getSimulators(false).then((emulators) => {
getSimulators(store, false).then((emulators) => {
setIosEmulators(
emulators.filter(
(device) =>
@@ -69,7 +73,7 @@ export const LaunchEmulatorDialog = withTrackingScope(
),
);
});
}, [iosEnabled, getSimulators]);
}, [iosEnabled, getSimulators, store]);
const items = [
...(androidEmulators.length > 0 ? [<AndroidOutlined />] : []),