From 0cfa51aa45084343df4b6f3612ab09e846ecf495 Mon Sep 17 00:00:00 2001 From: Daniel Imhoff Date: Thu, 30 May 2019 14:31:21 -0500 Subject: [PATCH] feat(android): better error messaging Catch the awful "ERR_UNSUITABLE_API_INSTALLATION" error during run and print something a bit more friendly. resolves https://github.com/ionic-team/native-run/issues/7 --- src/android/run.ts | 28 ++++++++++++++++++++++++++-- src/errors.ts | 6 +++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/android/run.ts b/src/android/run.ts index 83d60ef..56c374b 100644 --- a/src/android/run.ts +++ b/src/android/run.ts @@ -1,4 +1,6 @@ -import { CLIException, ERR_BAD_INPUT, ERR_TARGET_NOT_FOUND, RunException } from '../errors'; +import * as Debug from 'debug'; + +import { AVDException, CLIException, ERR_BAD_INPUT, ERR_NO_DEVICE, ERR_NO_TARGET, ERR_TARGET_NOT_FOUND, ERR_UNSUITABLE_API_INSTALLATION, RunException } from '../errors'; import { getOptionValue, getOptionValues } from '../utils/cli'; import { log } from '../utils/log'; import { onBeforeExit } from '../utils/process'; @@ -9,6 +11,8 @@ import { getInstalledAVDs } from './utils/avd'; import { installApkToDevice, selectDeviceByTarget, selectHardwareDevice, selectVirtualDevice } from './utils/run'; import { SDK, getSDK } from './utils/sdk'; +const modulePrefix = 'native-run:android:run'; + export async function run(args: ReadonlyArray): Promise { const sdk = await getSDK(); const apkPath = getOptionValue(args, '--app'); @@ -72,6 +76,8 @@ export async function run(args: ReadonlyArray): Promise { } export async function selectDevice(sdk: SDK, args: ReadonlyArray): Promise { + const debug = Debug(`${modulePrefix}:${selectDevice.name}`); + const devices = await getDevices(sdk); const avds = await getInstalledAVDs(sdk); @@ -93,8 +99,26 @@ export async function selectDevice(sdk: SDK, args: ReadonlyArray): Promi if (selectedDevice) { return selectedDevice; + } else if (args.includes('--device')) { + throw new RunException(`No hardware devices found. Not attempting emulator because --device was specified.`, ERR_NO_DEVICE); + } else { + log('No hardare devices found, attempting emulator...\n'); + } + } + + try { + return await selectVirtualDevice(sdk, devices, avds); + } catch (e) { + if (!(e instanceof AVDException)) { + throw e; + } + + debug('Issue with AVDs: %s', e.message); + + if (e.code === ERR_UNSUITABLE_API_INSTALLATION) { + throw new RunException('No targets available. Cannot create AVD because there is no suitable API installation. Use --sdk-info to reveal missing packages and other issues.', ERR_NO_TARGET); } } - return selectVirtualDevice(sdk, devices, avds); + throw new RunException('No targets available.', ERR_NO_TARGET); } diff --git a/src/errors.ts b/src/errors.ts index 55fc5bb..41b2832 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -34,6 +34,8 @@ export const ERR_SDK_NOT_FOUND = 'ERR_SDK_NOT_FOUND'; export const ERR_SDK_PACKAGE_NOT_FOUND = 'ERR_SDK_PACKAGE_NOT_FOUND'; export const ERR_SDK_UNSATISFIED_PACKAGES = 'ERR_SDK_UNSATISFIED_PACKAGES'; export const ERR_TARGET_NOT_FOUND = 'ERR_TARGET_NOT_FOUND'; +export const ERR_NO_DEVICE = 'ERR_NO_DEVICE'; +export const ERR_NO_TARGET = 'ERR_NO_TARGET'; export const ERR_UNKNOWN_AVD = 'ERR_UNKNOWN_AVD'; export const ERR_UNSUPPORTED_API_LEVEL = 'ERR_UNSUPPORTED_API_LEVEL'; @@ -74,7 +76,9 @@ export class EmulatorException extends Exception {} export type RunExceptionCode = ( typeof ERR_NO_AVDS_FOUND | - typeof ERR_TARGET_NOT_FOUND + typeof ERR_TARGET_NOT_FOUND | + typeof ERR_NO_DEVICE | + typeof ERR_NO_TARGET ); export class RunException extends Exception {}